条件移动最大值

时间:2011-08-18 23:33:33

标签: r

我是一个相对的R菜鸟。

我有一个看起来像这样的大数据集:

         Tempadjvolt      newmass     rgdeltas
2794       498.5777  0.5355647187   0.00000000
2795       499.7577  0.5355647187   0.00000000
2796       500.7877  0.3415104788  -2.87487763
2797       502.1177  0.4312854788  -1.54487763
2798       500.3877  0.5355647187   0.00000000
2799       502.5377  0.4596354788  -1.12487763
2800       507.6877  0.8072604788   4.02512237
2801       505.2577  0.6432354788   1.59512237
2802       505.7977  0.6796854788   2.13512237
2803       517.8877  1.4957604788  14.22512237
2804       502.2477  0.4400604788  -1.41487763
2805       507.3677  0.7856604788   3.70512237
2806       519.7277  1.6199604788  16.06512237
2807       528.9377  2.2416354788  25.27512237
2808       520.2677  1.6564104788  16.60512237
2809       519.3877  0.5355647187   0.00000000
2810       526.5677  2.0816604788  22.90512237
2811       519.5377  0.5355647187   0.00000000
2812       526.9277  2.1059604788  23.26512237
2813       529.9877  2.3125104788  26.32512237
2814       514.4077  1.2608604788  10.74512237
2815       518.3777  1.5288354788  14.71512237

我正在尝试识别负的rgdeltas值[例如,第2804行],然后“查看”后面和前面的7个位置以找到最高的Tempadjvolt并将行2804的tempadjvolt设置为该局部最大值。

帧长约4000行,其中~515是负值。我试了几个for循环,但是还吐了一堆NAs - 这让我觉得它们构造不当/不正确。

非常感谢任何协助。

正如评论中指出的那样,原帖不清楚。我不关心连续的负rgdeltas值。对于帧的前端和末端7内的负值,理想情况下,循环将在开始/结束之前前后看多少个位置。此时不那么关心。

更多背景: 这是最初用C#编写的信号处理程序的一部分,我试图转移到R,以增加对环境监视器输出的大量文件的一些更简便的批处理。我没有编写原始代码,这只是一大堆内容的一小部分。

我很感激帮助。谢谢!

2 个答案:

答案 0 :(得分:5)

1)零填充。假设数据框名为DF,我们在zoo包中使用rollapply将函数f应用于宽度为15的移动窗口:

library(zoo)
# columns of DF are (1) Tempadjvolt, (2) newmass and (3) rgdeltas
f <- function(x) if (x[8, 3] < 0) max(x[, 1]) else x[8, 1]
DF[[1]] <- rollapply(DF, 15, f, fill = 0, by.column = FALSE)

在上面我们用零填充了开头和结尾附近的点,因为看起来处理这个问题的确切方法并不那么重要,但我们可以使用其他一些填充值。

2)保留结束值。另一种可能性是仅处理不在末端附近的点:

DF[seq(8, nrow(DF)-7), 1] <- rollapply(DF, 15, f, by.column = FALSE)

3)部分。或者我们可以使用partial = TRUE,然后在这两端附近获取部分值的max,如下所示:

f2 <- function(x) { 
      # Columns of DF2 are (1) Tempadjvolt, (2) newmass, (3) rgdeltas and (4) seq.
      # Condition is TRUE if passed a partial x near the beginning.
      # k is row index of current row in x. Normally 8 but near start it varies.
      k <- if (x[1, 4] == 1) nrow(x) - 7 else 8
      if (x[k,  3] < 0) max(x[, 1]) else x[k, 1]
}
DF2 <- cbind(DF, seq = 1:nrow(DF))
DF[[1]] <- rollapply(DF2, 15, f2, partial = TRUE, by.column = FALSE)

答案 1 :(得分:4)

假设其名称为dat

negidxs <- as.numeric( rownames(dat)[ dat[[3]] < 0 ] )
 for ( i in negidxs ){ 
      dat[as.character(i), "Tempadjvolt"] <- 
            max(dat[rownames(dat) %in% (i-7):(i+7), "Tempadjvolt"], na.rm=TRUE) }
 dat
  #----------------------------------#
     Tempadjvolt   newmass  rgdeltas
2794    498.5777 0.5355647  0.000000
2795    499.7577 0.5355647  0.000000
2796    517.8877 0.3415105 -2.874878
2797    517.8877 0.4312855 -1.544878
2798    500.3877 0.5355647  0.000000
2799    519.7277 0.4596355 -1.124878
2800    507.6877 0.8072605  4.025122
2801    505.2577 0.6432355  1.595122
2802    505.7977 0.6796855  2.135122
#snipped-----