Ich stimme der Antwort von whuber zu, wollte aber nur hinzufügen, dass der "+2" -Teil des Codes, der versucht, den Index zu verschieben, um dem neu gefundenen Peak zu entsprechen, tatsächlich "überschießt" und "+1" sein sollte. Im vorliegenden Beispiel erhalten wir zum Beispiel:
> findPeaks(cc)
[1] 3 22 41 59 78 96
Wenn wir diese gefundenen Peaks in einem Diagramm hervorheben (fett rot):
wir sehen, dass sie konstant 1 Punkt vom tatsächlichen Peak entfernt sind.
Konsequenz
pks[x[pks - 1] - x[pks] > thresh]
sollte pks[x[pks] - x[pks + 1] > thresh]
oder seinpks[x[pks] - x[pks - 1] > thresh]
GROSSES UPDATE
Nach meiner eigenen Suche nach einer adäquaten Peak-Finding-Funktion habe ich folgendes geschrieben:
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
}
Ein „Peak“ ist definiert als ein lokales Maximum, bei dem die m
Punkte auf beiden Seiten kleiner sind als es. m
Je größer der Parameter , desto strenger ist daher das Spitzenfinanzierungsverfahren. so:
find_peaks(cc, m = 1)
[1] 2 21 40 58 77 95
Die Funktion kann auch verwendet werden, um lokale Minima eines sequentiellen Vektors x
über zu finden find_peaks(-x)
.
Hinweis: Ich habe jetzt die Funktion auf gitHub gesetzt, falls jemand sie benötigt: https://github.com/stas-g/findPeaks