I'm trying to find "peaks" in a vector, i.e. elements for which the nearest neighboring elements on both sides that do not have the same value have lower values.
So, e.g. in the vector
c(0,1,1,2,3,3,3,2,3,4,5,6,5,7)
there are peaks at positions 5,6,7,12 and 14
Finding local maxima and minima comes close, but doesn't quite fit.
This should work. The call to diff(sign(diff(x)) == -2
finds peaks by, in essence, testing for a negative second derivative at/around each of the unique values picked out by rle
.
x <- c(0,1,1,2,3,3,3,2,3,4,5,6,5,7)
r <- rle(x)
which(rep(x = diff(sign(diff(c(-Inf, r$values, -Inf)))) == -2,
times = r$lengths))
# [1] 5 6 7 12 14
(I padded your vector with -Inf
s so that both elements 1 and 14 have the possibility of being matched, should the nearest different-valued element have a lower value. You can obviously adjust the end-element matching rule by instead setting one or both of these to Inf
.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With