【问题标题】:Rolling sum in specified range指定范围内的滚动和
【发布时间】:2017-10-21 16:11:01
【问题描述】:

对于 df,我想获取过去 10 秒内 Value 列的滚动总和,时间以秒为单位。数据框非常大,因此不能使用 dply::complete (数百万个数据点,毫秒级)。我更喜欢 dplyr 解决方案,但认为数据表 left_join 可能是可行的,只是无法使其工作。

df = data.frame(Row=c(1,2,3,4,5,6,7),Value=c(4,7,2,6,3,8,3),Time=c(10021,10023,10027,10035,10055,10058,10092))

解决方案将添加一个列 (Sum.10S),该列采用过去 10 秒的滚动总和:

df$Sum.10S=c(4,11,13,8,3,11,3)

【问题讨论】:

  • 将第三个数字固定为 13 以反映评论。因此,第三行的时间为 10027,并将最后十秒的值相加(10021 处为 4,10023 处为 7,10027 处为 2)
  • 当你说“最后”时,你是指前十秒吗?因此,对于您的 data.frame,第 1 行将是 1:1 行的总和。第 2 行将是第 1:2 行的总和。第 3 行将是第 1:3 行的总和。第 4 行将是第 3:4 行的总和。第 5 行将是第 5:5 行的总和。第 6 行将是第 5:6 行的总和。第 7 行将是第 7:7 行的总和?我理解你的目标吗?
  • 是的,没错。

标签: r dplyr data.table


【解决方案1】:

定义一个函数sum10,对最后 10 秒求和,并将其与rollapplyr 一起使用。它避免了显式循环,并且运行速度比使用问题中的数据显式循环快 10 倍左右。

library(zoo)

sum10 <- function(x) {
  if (is.null(dim(x))) x <- t(x)
  tt <- x[, "Time"]
  sum(x[tt >= tail(tt, 1) - 10, "Value"])
}

transform(df, S10 = rollapplyr(df, 10, sum10, by.column = FALSE, partial = TRUE))

给予:

  Row Value  Time  S10
1   1     4 10021    4
2   2     7 10023   11
3   3     2 10027   13
4   4     6 10035    8
5   5     3 10055    3
6   6     8 10058   11
7   7     3 10092    3

【讨论】:

    【解决方案2】:

    好吧,我的速度不够快,无法获得第一个答案。但是这个解决方案更简单,并且不需要外部库。

    df = data.frame(Row=c(1,2,3,4,5,6,7),Value=c(4,7,2,6,3,8,3),Time=c(10021,10023,10027,10035,10055,10058,10092))
    
    df$SumR<-NA
    for(i in 1:nrow(df)){
      df$SumR[i]<-sum(df$Value[which(df$Time<=df$Time[i] & df$Time>=df$Time[i]-10)])
      }
    
      Row Value  Time SumR
    1   1     4 10021    4
    2   2     7 10023   11
    3   3     2 10027   13
    4   4     6 10035    8
    5   5     3 10055    3
    6   6     8 10058   11
    7   7     3 10092    3
    

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-22
      • 2018-03-05
      • 2015-03-13
      • 2012-06-19
      • 1970-01-01
      相关资源
      最近更新 更多