2016-08-15 52 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

不客气。如果问题得到满意答复,请接受答案。 –