在另一列中按滞后值移动行值

时间:2016-12-12 21:10:04

标签: r performance data.table

我有一个相当大的数据集,我对&#34;行进&#34;感兴趣值根据另一列的值向前推进。例如,如果use strict; use warnings 'all'; use JSON; use Data::Dumper; my $json_str = do { open my $fh, '<', 'sims/pgcache/.gsim/metadata.txt' or die $!; local $/; <$fh>; }; my $metadata = from_json $json_str; print STDERR "json_str = $json_str\n"; print Dumper( "metadata", $metadata ); 位于Value = 3Time = 0,我希望3将两行向下移动到DesiredShift = 2。这是一个可重复的例子。

构建可重现的伪数据

Time = 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处的值为{3},因此第3行的DesiredOutput列将等于3 Time=1Value = 3

第4行显示3 + 4 = 7,因为3次向下移动2次,4次向下移动1次。

我希望ID组可以做到这一点,并希望能够利用 Shift = 2 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函数来解决这个问题,但我不确定如何使用多个滞后参数来完成这项工作。

1 个答案:

答案 0 :(得分:6)

试试这个:

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