Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding peaks in vector

Tags:

r

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.

like image 752
RoyalTS Avatar asked Feb 18 '23 19:02

RoyalTS


1 Answers

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 -Infs 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.)

like image 87
Josh O'Brien Avatar answered Feb 21 '23 08:02

Josh O'Brien