Detecting cycle maxima (peaks) in noisy time series (In R?) [closed]

风格不统一 提交于 2019-11-30 07:39:33

问题


This question is about an algorithm for determining the number and location of maxima in a sequence of numbers. Thus, there is a statistical flavor to the question, but it is more leaning towards programming, because I am not interested in the specific statistical properties, and the solution needs to be in R. The use of statistics to answer this question is OK, but not a requirement.

I want to extract maxima of cycles in time series data (i.e., an ordered sequence of numbers). An example of such data is the solar flare time series (~11 year cycle, between 9 & 14 years). The cycles don't repeat at a perfect interval, and the peaks aren't always the same height.

I found a recent paper describing an algorithm for this, and the paper actually uses solar flares as an example (Figure 5, Scholkmann et al. 2012, Algorithms). I was hoping that this algorithm, or an equally effective algorithm, was available as an R package.

Link to Scholkmann paper on "automatic multiscale-based peak detection" http://www.mdpi.com/1999-4893/5/4/588

I've tried the "turningpoints" function in the "pastecs" package but it seemed to be too sensitive (i.e., detected too many peaks). I thought of trying to smooth the time series first, but I'm not sure if this is the best approach (I'm no expert).

Thanks for any pointers.


回答1:


If the peaks are almost periodic (with a slowly fluctuating period), as in the sunspot example, you can use the Hilbert transform or the empirical mode decomposition to smooth the time series.

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 )




回答2:


Here is a solution involving the wmtsa package in R. I added my own little function to facilitate the searching of maxima once the wmtsa::wavCWTPeaks got it close.

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)



来源:https://stackoverflow.com/questions/16341717/detecting-cycle-maxima-peaks-in-noisy-time-series-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!