I agree with whuber's response but just wanted to add that the "+2" portion of the code, which attempts to shift the index to match the newly found peak actually 'overshoots' and should be "+1". for instance in the example at hand we obtain:
> findPeaks(cc)
[1] 3 22 41 59 78 96
when we highlight these found peaks on a graph (bold red):

we see that they are consistently 1 point away from the actual peak.
consequenty
pks[x[pks - 1] - x[pks] > thresh]
should be pks[x[pks] - x[pks + 1] > thresh]
or pks[x[pks] - x[pks - 1] > thresh]
BIG UPDATE
following my own quest to find an adequate peak finding function i wrote this:
find_peaks <- function (x, m = 3){
shape <- diff(sign(diff(x, na.pad = FALSE)))
pks <- sapply(which(shape < 0), FUN = function(i){
z <- i - m + 1
z <- ifelse(z > 0, z, 1)
w <- i + m + 1
w <- ifelse(w < length(x), w, length(x))
if(all(x[c(z : i, (i + 2) : w)] <= x[i + 1])) return(i + 1) else return(numeric(0))
})
pks <- unlist(pks)
pks
}
a 'peak' is defined as a local maxima with m
points either side of it being smaller than it. hence, the bigger the parameter m
, the more stringent is the peak funding procedure. so:
find_peaks(cc, m = 1)
[1] 2 21 40 58 77 95
the function can also be used to find local minima of any sequential vector x
via find_peaks(-x)
.
Note: i have now put the function on gitHub if anyone needs it: https://github.com/stas-g/findPeaks
findPeaks
appears in my reply, @Adam. BTW, the package is "quantmod". $\endgroup$ – whuber♦ Feb 16 '12 at 19:02