R中group_by内的条件最大/最小值

时间:2016-03-25 16:18:18

标签: r group-by max dplyr minimum

我一直在寻找一个没有太多运气的答案,所以手指交叉有人可​​以帮助我!

我正在处理周期性数据,我正在尝试找到两个峰值和两个波谷的相关值 - 这不必等于最大值/最小值和第二个最大值/最小值,而是最大值/ min,然后是第二个max / min值,条件是值大于/小于前一个值和后一个值。

这是一个循环的例子

x <- c(3.049, 3.492, 3.503, 3.429, 3.013, 2.881, 2.29, 1.785, 1.211, 0.890, 0.859, 0.903, 1.165, 1.634, 2.073, 2.477, 3.162, 3.207, 3.177, 2.742, 2.24, 1.827, 1.358, 1.111, 1.063, 1.098, 1.287, 1.596, 2.169, 2.292)

我有1000个周期,所以我在dplyr中使用group_by对周期进行分组,然后希望在组内应用条件max / min参数。

我很感激有这方面的建议,

提前致谢

修改

我已经使用了以下功能,只需在最后一行进行轻微编辑

  return(data.frame(Data.value=x, Time=y, Date=z,HHT=peak, LLT=trough)) 

其中x是我上面的原始x,y是时间var,z是日期变量。这允许我对结果做一些额外的计算(我需要值为min / max的时间以及值本身)。

所以现在我有一个数据框,其中包含我需要的所有内容,但它仅适用于一个日期 - 我仍然无法使用group_by函数在整个数据集中运行。我已尝试使用

按日期进行子设置

subsets<-split(data, data$datevar, drop=TRUE)

但仍需要一种方法以某种方式为每个子集运行findminmax函数(以及我的几行额外代码)。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

考虑以下可以在dplyr group_by()过程中传递的自定义函数。本质上,函数遍历循环值列表并比较它之前和之后的邻居。峰值的邻居既低于自身,也有邻居大于自己的低谷。

findminmax <- function(x){
  peak <- list(NA, NA)                              # INITIALIZE TEMP LISTS AND ITERATORS
  p <- 1
  trough <- list(NA, NA)
  t <- 1

  for (i in 1:length(x)){
    if (i != 1 & i != length(x)){                   # LEAVES OUT FIRST AND LAST VALUES
      if ((x[i] > x[i-1]) & (x[i] > x[i+1])) {      # COMPARES IF GREATER THAN NEIGHBORS
        peak[p] <- x[i]
        p <- p + 1
      }
      if ((x[i] < x[i-1]) & (x[i] < x[i+1])){       # COMPARES IF LESS THAN NEIGHBORS
        trough[t] <- x[i]
        t <- t + 1
      }
    }
  }
  return(list(peak1=peak[[1]], peak2=peak[[2]], 
              trough1=trough[[1]], trough2=trough[[2]]))
}

result <- findminmax(x)
#$peak1
#[1] 3.503    
#$peak2
#[1] 3.207    
#$trough1
#[1] 0.859    
#$trough2
#[1] 1.063

对于dplyr的group_by:

finaldf <- originaldf %>% 
             group_by(z) %>% 
                summarise(Time = mean(y),
                          HHT1 = findminmax(x)$peak1,
                          HHT2 = findminmax(x)$peak2,
                          LLT1 = findminmax(x)$trough1,
                          LLT2 = findminmax(x)$trough2)