【问题标题】:rolling computation for following or previous values in a data.table滚动计算 data.table 中的后续或先前值
【发布时间】:2020-11-09 09:32:02
【问题描述】:

我有一个 data.table DT 有 3 列,ZeitSpuerEingriff

DT <- data.table(Zeit = c(1, 2, 3, 4, 5, 6, 7, 8, 9), 
                 Spuer = c(45, 45, 32, 25, 30, 44, 34, 42, 44), 
                 Eingriff = c(0, 0, 1, 0, 0, 0, 1, 0, 0))

我想知道Eingriff == 1Spuer &lt; 30 的下三个值之一。如果它是 TRUE 则 Eingriff == 1 否则 Eingriff == 0。对于我的真实数据,我会检查Spuer 中接下来的 20 个或更多值是否小于 30,因此像lead(Spuer, 1)、lead(Spuer, 2) 等解决方案不是一个好的解决方案。

我已经尝试使用frollapplyshift 实施解决方案,但无法实现。

最终结果应该是这样的:

res <- data.table(Zeit = c(1, 2, 3, 4, 5, 6, 7, 8, 9), 
                  Spuer = c(45, 45, 32, 25, 30, 44, 34, 42, 44), 
                  Eingriff = c(0, 0, 1, 0, 0, 0, 0, 0, 0))

【问题讨论】:

    标签: r data.table compare rolling-computation


    【解决方案1】:

    这是使用sapply 的一个选项:

    我们首先找出Eingriff == 1 所在的索引,并针对每个索引检查window 中值的any 是否小于30。

    library(data.table)
    
    window <- 3
    inds <- which(DT$Eingriff == 1)
    
    DT[inds, Eingriff := as.integer(sapply(inds, function(x) 
                                  any(DT$Spuer[x:(x+window - 1)] < 30)))]
    
    DT
    #   Zeit Spuer Eingriff
    #1:    1    45        0
    #2:    2    45        0
    #3:    3    32        1
    #4:    4    25        0
    #5:    5    30        0
    #6:    6    44        0
    #7:    7    34        0
    #8:    8    42        0
    #9:    9    44        0
    

    【讨论】:

      【解决方案2】:

      这是另一个使用非等连接的选项:

      k <- 3L
      DT[, c("start", "end") := .(.I, .I + k)]
      DT[Eingriff==1L, Eingriff :=
          DT[.SD, on=.(start>start, start<=end), by=.EACHI, +any(x.Spuer < 30)]$V1
      ]
      

      输出:

         Zeit Spuer Eingriff start end
      1:    1    45        0     1   4
      2:    2    45        0     2   5
      3:    3    32        1     3   6
      4:    4    25        0     4   7
      5:    5    30        0     5   8
      6:    6    44        0     6   9
      7:    7    34        0     7  10
      8:    8    42        0     8  11
      9:    9    44        0     9  12
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-15
        • 1970-01-01
        • 2012-05-21
        • 1970-01-01
        • 2018-09-30
        • 1970-01-01
        • 2013-04-15
        相关资源
        最近更新 更多