I\'m looking for a computationally efficient way to find local maxima/minima for a large list of numbers in R.
Hopefully without for
loops...
For exampl
Answer by @42- is great, but I had a use case where I didn't want to use zoo
. It's easy to implement this with dplyr
using lag
and lead
:
library(dplyr)
test = data_frame(x = sample(1:10, 20, replace = TRUE))
mutate(test, local.minima = if_else(lag(x) > x & lead(x) > x, TRUE, FALSE)
Like the rollapply
solution, you can control the window size and edge cases through the lag
/lead
arguments n
and default
, respectively.
Late to the party, but this might be of interest for others. You can nowadays use the (internal) function find_peaks
from ggpmisc
package. You can parametrize it using threshold
, span
and strict
arguments. Since ggpmisc
package is aimed for using with ggplot2
you can directly plot minima and maxima using thestat_peaks
and stat_valleys
functions:
set.seed(1)
x <- 1:10
y <- runif(10)
# Maxima
x[ggpmisc:::find_peaks(y)]
[1] 4 7
y[ggpmisc:::find_peaks(y)]
[1] 0.9082078 0.9446753
# Minima
x[ggpmisc:::find_peaks(-y)]
[1] 5
y[ggpmisc:::find_peaks(-y)]
[1] 0.2016819
# Plot
ggplot(data = data.frame(x, y), aes(x = x, y = y)) + geom_line() + stat_peaks(col = "red") + stat_valleys(col = "green")