首页 > 解决方案 > R data.table:按组滚动前 3 天的滞后总和

问题描述

我目前在 data.table 中使用 R 并正在寻找一种简单的方法来实现滚动滞后总和。我可以找到有关滞后的帖子和有关各种 sum 函数的帖子,但没有成功找到一个以我希望实现它的方式(回滚 3 天)将 sum 和 lag 结合在一起的帖子。

我有一个类似于以下的数据集 -

id  agedays  diar
1    1        1
1    2        0
1    3        1
1    4        1
1    5        0
1    6        0
1    7        0
1    8        1
1    9        1
1    10       1
3    2        0
3    5        0
3    6        0
3    8        1
3    9        1
4    1        0
4    4        0
4    5        0
4    6        1
4    7        0

我想创建一个变量“diar_prev3”,它保存当前 agedays 值之前过去 3 天的 diar 滚动总和。对于 agedays < 4 的行,Diar_prev3 将为 NA 数据集如下所示:

id  agedays  diar  diar_prev3
1    1        1      NA
1    2        0      NA
1    3        1      NA
1    4        1      2
1    5        0      2
1   6        0      2
1    7        0      1
1    8        1      0
1    9        1      1
1    10       1      2
3    2        0      NA
3    5        0      0
3    6        0      0
3    8        1      0
3    9        1      1
4    1        0      NA
4    4        0      0
4    5        0      0
4    6        1      0
4    7        0      1

我尝试了一个基本的滞后函数,但不确定如何使用包含的滚动求和函数来实现它。有没有人推荐使用任何功能来完成此操作?

****已编辑以修复 ID==2 的错误

标签: rdata.table

解决方案


我不明白逻辑;它似乎不是 by id,否则 id==2 的结果没有意义 - 但是 id==3 和 4 发生了什么?

原则上,您可以通过 ID 或不通过 ID 执行以下操作:

library(data.table)
library(RcppRoll)
DT <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
                            3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L), 
                     agedays = c(1L, 2L, 
                                 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 2L, 5L, 6L, 8L, 9L, 1L, 4L, 
                                 5L, 6L, 7L), diar = c(1L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 1L, 
                                                       0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 0L)), 
                class = "data.frame", row.names = c(NA, -20L))

setDT(DT)
DT[, diar_prev3 := ifelse(agedays < 4, NA, RcppRoll::roll_sum(lag(diar, 1), n=3L, fill=NA, align = "right"))][]
#>     id agedays diar diar_prev3
#>  1:  1       1    1         NA
#>  2:  1       2    0         NA
#>  3:  1       3    1         NA
#>  4:  1       4    1          2
#>  5:  1       5    0          2
#>  6:  2       6    0          1
#>  7:  2       7    0          0
#>  8:  2       8    1          1
#>  9:  2       9    1          2
#> 10:  2      10    1          3
#> 11:  3       2    0         NA
#> 12:  3       5    0          1
#> 13:  3       6    0          0
#> 14:  3       8    1          1
#> 15:  3       9    1          2
#> 16:  4       1    0         NA
#> 17:  4       4    0          1
#> 18:  4       5    0          0
#> 19:  4       6    1          1
#> 20:  4       7    0          1
DT[, diar_prev3 := ifelse(agedays < 4, NA, RcppRoll::roll_sum(lag(diar, 1), n=3L, fill=NA, align = "right")), by=id][]
#>     id agedays diar diar_prev3
#>  1:  1       1    1         NA
#>  2:  1       2    0         NA
#>  3:  1       3    1         NA
#>  4:  1       4    1          2
#>  5:  1       5    0          2
#>  6:  2       6    0         NA
#>  7:  2       7    0         NA
#>  8:  2       8    1          1
#>  9:  2       9    1          2
#> 10:  2      10    1          3
#> 11:  3       2    0         NA
#> 12:  3       5    0         NA
#> 13:  3       6    0          0
#> 14:  3       8    1          1
#> 15:  3       9    1          2
#> 16:  4       1    0         NA
#> 17:  4       4    0         NA
#> 18:  4       5    0          0
#> 19:  4       6    1          1
#> 20:  4       7    0          1

reprex 包(v0.3.0)于 2020-07-20 创建


推荐阅读