这个问题是关于确定数字序列中最大值的数量和位置的算法。因此,问题存在统计风格,但它更倾向于编程,因为我对特定的统计属性不感兴趣,并且解决方案需要在R中。使用统计数据来回答这个问题是可以的,但不是要求。
我想在时间序列数据中提取周期的最大值(即,有序的数字序列)。这种数据的一个例子是太阳耀斑时间序列(〜11年周期,9和14年之间)。循环不会以完美的间隔重复,并且峰值并不总是相同的高度。
我发现了一篇最近的论文,描述了一种算法,本文实际上以太阳耀斑为例(图5,Scholkmann等人,2012,算法)。我希望这个算法或同样有效的算法可用作R包。
链接到Scholkmann关于“基于自动多尺度峰值检测”的论文 http://www.mdpi.com/1999-4893/5/4/588
我在“pastecs”包中尝试了“转折点”功能,但它似乎太敏感了(即检测到太多峰值)。我想首先尝试平滑时间序列,但我不确定这是否是最好的方法(我不是专家)。
感谢您的任何指示。
答案 0 :(得分:3)
如果峰值几乎是周期性的(周期缓慢波动),如太阳黑子示例中所示, 您可以使用Hilbert transform或empirical mode decomposition来平滑时间序列。
library(EMD)
x <- as.vector(sunspots)
r <- emd(x)
# Keep 5 components -- you may need more, or less.
y <- apply( r$imf[,5:10], 1, sum ) + mean(r$residue)
plot(x, type="l", col="grey")
lines( y, type="l", lwd=2)
n <- length(y)
i <- y[2:(n-1)] > y[1:(n-2)] & y[2:(n-1)] > y[3:n]
points( which(i), y[i], pch=15 )
答案 1 :(得分:3)
这是一个涉及R中wmtsa
包的解决方案。我添加了自己的小函数,以便在wmtsa::wavCWTPeaks
将其关闭后便于搜索最大值。
PeakCycle <- function(Data=as.vector(sunspots), SearchFrac=0.02){
# using package "wmtsa"
#the SearchFrac parameter just controls how much to look to either side
#of wavCWTPeaks()'s estimated maxima for a bigger value
#see dRange
Wave <- wavCWT(Data)
WaveTree <- wavCWTTree(Wave)
WavePeaks <- wavCWTPeaks(WaveTree, snr.min=5)
WavePeaks_Times <- attr(WavePeaks, which="peaks")[,"iendtime"]
NewPeakTimes <- c()
dRange <- round(SearchFrac*length(Data))
for(i in 1:length(WavePeaks_Times)){
NewRange <- max(c(WavePeaks_Times[i]-dRange, 1)):min(c(WavePeaks_Times[i]+dRange, length(Data)))
NewPeakTimes[i] <- which.max(Data[NewRange])+NewRange[1]-1
}
return(matrix(c(NewPeakTimes, Data[NewPeakTimes]), ncol=2, dimnames=list(NULL, c("PeakIndices", "Peaks"))))
}
dev.new(width=6, height=4)
par(mar=c(4,4,0.5,0.5))
plot(seq_along(as.vector(sunspots)), as.vector(sunspots), type="l")
Sunspot_Ext <- PeakCycle()
points(Sunspot_Ext, col="blue", pch=20)