data.table中的行条件列操作

Mar*_*ark 12 r data.table

我有一个大的data.table,其中每行我需要根据完整data.table的一部分进行计算.作为一个例子,考虑以下data.table,并假设我为每一行想要计算id2与当前行的id1匹配的每一行的num变量的总和,以及时间变量在距离时间1的距离内.当前行.

set.seed(123)

dat <- data.table(cbind(id1=sample(1:5,10,replace=T),
                        id2=sample(1:5,10,replace=T),
                        num=sample(1:10,10,replace=T),
                        time=sample(1:10,10,replace=T)))
Run Code Online (Sandbox Code Playgroud)

这可以通过像这样循环遍历每一行来轻松完成

dat[,val:= 0]
for (i in 1:nrow(dat)){
  this.val <- dat[ (id2==id1[i]) & (time>=time[i]-2) & (time<=time[i]+2),sum(num)]
  dat[i,val:=this.val]
}

dat
Run Code Online (Sandbox Code Playgroud)

结果data.table如下所示:

   > dat
        id1 id2 num time val
     1:   2   5   9   10   6
     2:   4   3   7   10   0
     3:   3   4   7    7  10
     4:   5   3  10    8   9
     5:   5   1   7    1   2
     6:   1   5   8    5   6
     7:   3   2   6    8  17
     8:   5   1   6    3  10
     9:   3   2   3    4   0
    10:   3   5   2    3   0
Run Code Online (Sandbox Code Playgroud)

使用data.table执行此类操作的正确/快速方法是什么?

akr*_*run 5

我们可以通过创建'timeminus2'和'timeplus2'列来使用自连接,on通过'id2'和'id1'连接,使用非等逻辑条件来获取sum'num'和assign(:=)'val' '到原始数据集的列

tmp <- dat[.(id1 = id1, timeminus2 = time - 2, timeplus2 = time + 2), 
             .(val = sum(num)),
             on = .(id2 = id1, time >= timeminus2, time <= timeplus2),
             by = .EACHI
         ][is.na(val), val := 0][]
dat[, val := tmp$val][]
#     id1 id2 num time val
# 1:   2   5   9   10   6
# 2:   4   3   7   10   0
# 3:   3   4   7    7  10
# 4:   5   3  10    8   9
# 5:   5   1   7    1   2
# 6:   1   5   8    5   6
# 7:   3   2   6    8  17
# 8:   5   1   6    3  10
# 9:   3   2   3    4   0
#10:   3   5   2    3   0
Run Code Online (Sandbox Code Playgroud)