R 按另一列中的滞后值移动行值
我有一个相当大的数据集,我感兴趣的是根据另一列的值在时间上“前进”。例如,如果我在R 按另一列中的滞后值移动行值,r,performance,data.table,R,Performance,Data.table,我有一个相当大的数据集,我感兴趣的是根据另一列的值在时间上“前进”。例如,如果我在时间=0时有一个值=3和一个所需的移位=2,我希望3向下移动两行,使之位于时间=2。这是一个可复制的例子 建立可复制的假数据 我希望每个值根据shift列向前移动。所以 第3行的DesiredOutput列将等于3,因为Time=1时的值为 Value=3和Shift=2 第4行显示了3+4=7,因为3次下移2,4次下移1 我希望能够做到这一点的ID组,并希望利用这一优势 由于速度对这个问题很重要,所以表 期望结果
时间=0时有一个值=3
和一个所需的移位=2
,我希望3向下移动两行,使之位于时间=2
。这是一个可复制的例子
建立可复制的假数据
我希望每个值根据shift
列向前移动。所以
第3行的DesiredOutput
列将等于3,因为Time=1时的值为
Value=3
和Shift=2
第4行显示了3+4=7,因为3次下移2,4次下移1
我希望能够做到这一点的ID组,并希望利用这一优势
由于速度对这个问题很重要,所以表
期望结果
我希望使用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
是的,我发布了几乎相同的东西,尽管你的最后一步是做不必要的复制。您可能可以使用dat[toMerge,on=“TargetIndex”,DesiredOutput:=i.Out]
来代替。我想行索引可能比合并更便宜:m=dat[,(rid=Shift+.i,v=Value)][rid ThistoMerge=dat[,list(Out=sum(Value)),by='TargetIndex']
part对于大型数据集来说是非常昂贵的,但我不确定如何避免它。@Mike.Gahan一般来说,我怀疑你能做到。Fwiw,这个答案已经优化了按组求和。请参见?GForce
# 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
# 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
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