我有一个相当大的数据集,我有兴趣根据另一列的值向前推进“行进”值.例如,如果我在时间= 0时有一个值= 3且DesiredShift = 2,我希望3向下移动两行,使其处于时间= 2.这是一个可重现的例子
构建可重现的伪数据
library(data.table) set.seed(1) rowsPerID <- 8 dat <- CJ(1:2, 1:rowsPerID) setnames(dat, c("ID","Time")) dat[, Value := rpois(.N, 4)] dat[, Shift := sample(0:2, size=.N, replace=TRUE)]
假数据
# ID Time Value Shift # 1: 1 1 3 2 # 2: 1 2 3 2 # 3: 1 3 4 1 # 4: 1 4 7 2 # 5: 1 5 2 2 # 6: 1 6 7 0 # 7: 1 7 7 1 # 8: 1 8 5 0 # 9: 2 1 5 0 # 10: 2 2 1 1 # 11: 2 3 2 0 # 12: 2 4 2 1 # 13: 2 5 5 2 # 14: 2 6 3 1 # 15: 2 7 5 1 # 16: 2 8 4 1
我希望每个Value根据Shift列向前移动.所以
由于Time = 1的值为,因此第3行的DesiredOutput列将等于3
值= 3且Shift = 2.
第4行显示3 4 = 7,因为3次向下移动2次,4次向下移动1次.
我想能够通过ID小组做到这一点,并希望利用
data.table因为速度是这个问题的关注点.
期望的结果
# ID Time Value Shift DesiredOutput # 1: 1 1 3 2 NA # 2: 1 2 3 2 NA # 3: 1 3 4 1 3 # 4: 1 4 7 2 3+4 = 7 # 5: 1 5 2 2 NA # 6: 1 6 7 0 7+7 = 14 # 7: 1 7 7 1 2 # 8: 1 8 5 0 7+5 = 12 # 9: 2 1 5 0 5 # 10: 2 2 1 1 NA # 11: 2 3 2 0 1+2 = 3 # 12: 2 4 2 1 NA # 13: 2 5 5 2 2 # 14: 2 6 3 1 NA # 15: 2 7 5 1 3+5=8 # 16: 2 8 4 1 5
我希望使用data.table :: shift函数来解决这个问题,但我不确定如何使用多个滞后参数来完成这项工作.
试试这个:dat[, TargetIndex:= .I + Shift] toMerge = dat[, list(Out = sum(Value)), by='TargetIndex'] dat[, TargetIndex:= .I] # dat = merge(dat, toMerge, by='TargetIndex', all=TRUE) dat[toMerge, on='TargetIndex', DesiredOutput:= i.Out] > dat # ID Time Value Shift TargetIndex DesiredOutput # 1: 1 1 3 2 1 NA # 2: 1 2 3 2 2 NA # 3: 1 3 4 1 3 3 # 4: 1 4 7 2 4 7 # 5: 1 5 2 2 5 NA # 6: 1 6 7 0 6 14 # 7: 1 7 7 1 7 2 # 8: 1 8 5 0 8 12 # 9: 2 1 5 0 9 5 # 10: 2 2 1 1 10 NA # 11: 2 3 2 0 11 3 # 12: 2 4 2 1 12 NA # 13: 2 5 5 2 13 2 # 14: 2 6 3 1 14 NA # 15: 2 7 5 1 15 8 # 16: 2 8 4 1 16 5