簡體   English   中英

在R中找到時間序列峰值的開始和結束

[英]Finding start and end of a peak in time series in R

我正在研究NDVI Time-Series數據,該數據一年中有23 observations 我能夠檢測出在14-19 14 - 19 observation之間出現的峰值。 現在我想找到start and end of the Peakstart and end of the Peak 我可以通過使用diff function查找符號變化來找到峰值的開始和結束。 但是在某些情況下,我注意到能夠找到終點,因為高峰的終點是明年。 解決方法是在23次觀察后重復這些值,使其循環並找到終點。

下面給出的示例將詳細說明該問題

x = c(250.7943,292.2904,340.459,368.811,363.4534,330.2302,291.6527,275.2815,299.9305,367.0331,461.2618,559.0772,639.6197,691.723,713.9833,709.5409,680.4415,626.1153,547.0395,450.4623,353.0839,277.257,241.597)

在此處輸入圖片說明

在此處輸入圖片說明

我正在尋找兩個方向的峰頂變化跡象,並且能夠找到在8觀察時峰的起點,但是當我尋找從峰頂開始的終點時,直到23點我都找不到任何變化。在這種情況下,我應該在23處達到峰值的終點。如表所示,我已在Excel中手動重復了這些值以更改符號。

如何在R中做到這一點???

一種解決方案可能是,放置一個條件來檢查直到23個觀測值才發現符號變化,然后將所有23個值填充到向量的末尾,然后查找符號變化。

有沒有簡單的方法可以完成此任務???

另一種可能性:(1)用領先和落后的Inf填充您的值,以在時間序列的開始和結束處創建虛擬局部最小值*。 (2)查找所有極小值(包括虛擬對象)的索引。 (3)查找兩個最大值的下一個索引。

# pad values with Inf and get indexes of all local minima
i.mins  <- which(diff(sign(diff(c(Inf, x, Inf)))) == 2)

# index of max value
i.mx <- which.max(x)

# combine indexes of local minima and the max
i <- sort(c(i.mins, i.mx))

# select the two minima on either side of the max  
ix <- i[which(i == i.mx) + c(-1, 1)]
ix 
# [1]  8 23

plot(x, type = "b")
points(x = c(ix[1], i.mx, ix[2]),
       y = c(x[ix[1]], max(y), x[ix[2]]),
       col = c("blue", "red", "blue"), pch = 19, cex = 2)

在此處輸入圖片說明


*請參見例如查找局部最大值和最小值

這只是創建一個可重現的示例:

y = data.frame(x = x, y = c(x[2:length(x)], NA))
y$diff <- y$y - y$x 

然后,我們首先生成一個新列:

y$startEndPeak <- NA

之后,我們循環遍歷所有差異記錄的data.frame。 因此,我們通過將所有差異與之前的對應部分進行比較來確定起點/終點和峰:

for(i in 2:(nrow(y) - 1)){
  thisDif <- y$diff[i]
  prevDif <- y$diff[i-1]

  if (thisDif < 0 && prevDif > 0){
    y$startEndPeak[i] <- "start/end"
  }

  if (thisDif > 0 && prevDif < 0){
    y$startEndPeak[i] <- "peak"
  }

}
y

#         x        y     diff      startEndPeak
#   1  250.7943 292.2904  41.4961         <NA>
#   2  292.2904 340.4590  48.1686         <NA>
#   3  340.4590 368.8110  28.3520         <NA>
#   4  368.8110 363.4534  -5.3576    start/end
#   5  363.4534 330.2302 -33.2232         <NA>
#   6  330.2302 291.6527 -38.5775         <NA>
#   7  291.6527 275.2815 -16.3712         <NA>
#   8  275.2815 299.9305  24.6490         peak
#   9  299.9305 367.0331  67.1026         <NA>
#   10 367.0331 461.2618  94.2287         <NA>
#   11 461.2618 559.0772  97.8154         <NA>
#   12 559.0772 639.6197  80.5425         <NA>
#   13 639.6197 691.7230  52.1033         <NA>
#   14 691.7230 713.9833  22.2603         <NA>
#   15 713.9833 709.5409  -4.4424    start/end
#   16 709.5409 680.4415 -29.0994         <NA>
#   17 680.4415 626.1153 -54.3262         <NA>
#   18 626.1153 547.0395 -79.0758         <NA>
#   19 547.0395 450.4623 -96.5772         <NA>
#   20 450.4623 353.0839 -97.3784         <NA>
#   21 353.0839 277.2570 -75.8269         <NA>
#   22 277.2570 241.5970 -35.6600         <NA>
#   23 241.5970       NA       NA         <NA>

然后我們使用向量放置起點和終點

y$startEndPeak[which(y$startEndPeak == "start/end")] <- c("start", "end")
y
#            x        y     diff startEndPeak
# ...........
#   3  340.4590 368.8110  28.3520         <NA>
#   4  368.8110 363.4534  -5.3576        start
# ...........
#   8  275.2815 299.9305  24.6490         peak
# ...........
#   15 713.9833 709.5409  -4.4424          end
# ...........

Usimg Loki的方法我可以部分解決我的問題。

y = data.frame(x = x, y = c(x[2:length(x)], x[1]))

y$diff <- y$y - y$x
y$startEndPeak <- NA

for(i in 2:(nrow(y))){
  thisDif <- y$diff[i]
  prevDif <- y$diff[i-1]

  if (thisDif < 0 && prevDif > 0){
      y$startEndPeak[i] <- "peak"
     }


  if (thisDif > 0 && prevDif < 0){
      y$startEndPeak[i-1] <- "end"
      y$startEndPeak[i] <- "start"
   }
}

y
  #      x        y     diff startEndPeak
  # 250.7943 292.2904  41.4961         <NA>
  # 292.2904 340.4590  48.1686         <NA>
  # 340.4590 368.8110  28.3520         <NA>
  # 368.8110 363.4534  -5.3576         peak
  # 363.4534 330.2302 -33.2232         <NA>
  # 330.2302 291.6527 -38.5775         <NA>
  # 291.6527 275.2815 -16.3712          end
  # 275.2815 299.9305  24.6490        start
  # 299.9305 367.0331  67.1026         <NA>
  # 367.0331 461.2618  94.2287         <NA>
  # 461.2618 559.0772  97.8154         <NA>
  # 559.0772 639.6197  80.5425         <NA>
  # 639.6197 691.7230  52.1033         <NA>
  # 691.7230 713.9833  22.2603         <NA>
  # 713.9833 709.5409  -4.4424         peak
  # 709.5409 680.4415 -29.0994         <NA>
  # 680.4415 626.1153 -54.3262         <NA>
  # 626.1153 547.0395 -79.0758         <NA>
  # 547.0395 450.4623 -96.5772         <NA>
  # 450.4623 353.0839 -97.3784         <NA>
  # 353.0839 277.2570 -75.8269         <NA>
  # 277.2570 241.5970 -35.6600          end
  # 241.5970 250.7943   9.1973        start

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM