2016-08-15 91 views
0

我試圖找出數據集中的最大值/最小值,而我用下面的代碼:排除重複最大值R中

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) else 
return(numeric(0)) 
    }) 
    pks <- unlist(pks) 
    pks 
} 

從STA的克氏評論here。然而,在我的數據集有一些重複的最大值,所以當我運行的代碼,它返回

find_peaks(data$Value) 
[1] 9 19 30 42 43 56 69 80 92 107 118 130 143 154 164 176 188 199 211 222 234 245 

,其中數據點42和43具有相同的值。

在這樣的情況下,我希望它保持第一個值並拒絕第二個值。我對R(以及一般編碼)相當陌生,而且我一直無法找到一個好辦法來做到這一點。有什麼建議麼?

+0

我相信這個問題更適合StackOverflow。 – FisherDisinformation

+1

你如何分享一些樣本數據,以便我們可以玩這個功能呢?模擬數據(使用set seed)或使用'dput()'共享數據是首選。 – Gregor

+0

小心這個。考慮當你讓'x < - sin(seq(-10,10,.01))'並且計算峯值'p <-find_peaks(x)'時會發生什麼。對於k = ...- 1,0,1,2,...,每個值k * pi/2都會得到最大值。然而'length(unique(x [p]))'是'3'。 – shayaa

回答

1

首先,我修改find_peaks以使用basediff(它沒有na.pad參數)。唯一的修改是在結尾處將索引加1。 (檢查輸出,如果你有一個xts對象進行相應的修改。)

find_peaks <- function (x, m = 3){ 
    shape <- diff(sign(diff(x))) 
    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) else 
return(numeric(0)) 
    }) 
    pks <- unlist(pks) 
    pks + 1 
} 

使一些樣本數據(其中,如在評論中指出,較好的方法是你原來的問題包括):

set.seed(123) 
dat <- sample(1:10, 100, replace=TRUE) 
pks <- find_peaks(dat) 
plot(seq_along(dat), dat, type="l") 
points(pks, dat[pks], pch=16, col="red") 

enter image description here

問題是如何刪除連續的最大值。一種方法是識別連續的索引號,並將其刪除:

new_pks <- pks[c(TRUE, diff(pks)!=1)] 
plot(seq_along(dat), dat, type="l") 
points(pks, dat[pks], pch=16, col="red") 
points(new_pks, dat[new_pks], pch=16, col="blue") 

只保留藍點。

enter image description here

+0

謝謝!這對我有效。 – GeorgeSBF

+0

不客氣。如果問題得到滿意答覆,請接受答案。 –