Zgadzam się z odpowiedzią Whubera, ale chciałem tylko dodać, że część „+2” kodu, która próbuje przesunąć indeks w celu dopasowania do nowo znalezionego szczytu, w rzeczywistości „przekracza” i powinna wynosić „+1”. na przykład w omawianym przykładzie otrzymujemy:
> findPeaks(cc)
[1] 3 22 41 59 78 96
kiedy zaznaczymy te znalezione piki na wykresie (pogrubiona czerwona):
widzimy, że są one konsekwentnie 1 punkt od rzeczywistego szczytu.
konsekwencja
pks[x[pks - 1] - x[pks] > thresh]
powinien być pks[x[pks] - x[pks + 1] > thresh]
lubpks[x[pks] - x[pks - 1] > thresh]
DUŻA AKTUALIZACJA
podążając za własną misją znalezienia odpowiedniej funkcji znajdowania pików, napisałem to:
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
}
„szczyt” jest zdefiniowany jako lokalne maksima, przy czym m
punkty po obu jego stronach są mniejsze od niego. stąd im większy parametr m
, tym bardziej rygorystyczna jest procedura finansowania szczytowego. więc:
find_peaks(cc, m = 1)
[1] 2 21 40 58 77 95
funkcja może być również wykorzystana do znalezienia lokalnych minimów dowolnego wektora sekwencyjnego x
poprzez find_peaks(-x)
.
Uwaga: teraz umieściłem tę funkcję na gitHub, jeśli ktoś jej potrzebuje: https://github.com/stas-g/findPeaks