将data.table的子集分配给另一个data.table的子集

时间:2016-09-30 14:48:54

标签: r data.table

我有两个data.tables:

library(data.table)
dt1 <- data.table(A=1:10, B=1, C=2, D=3)
dt2 <- data.table(A2=5:9, B2=4, C2=5, D2=6)

我想将dt2中列B2和C2的元素分配给dt1中的列B和C,其中A = A2,这样我得到一个如下所示的表:

dt1
#      A B C D
#  1:  1 1 2 3
#  2:  2 1 2 3
#  3:  3 1 2 3
#  4:  4 1 2 3
#  5:  5 4 5 3
#  6:  6 4 5 3
#  7:  7 4 5 3
#  8:  8 4 5 3
#  9:  9 4 5 3
# 10: 10 1 2 3

我知道我一次可以分配一列:

id1 <- which(dt1$A %in% dt2$A2)
id2 <- which(dt2$A2 %in% dt1$A)
dt1$B[id1] <- dt2$B2[id2]
dt1$C[id1] <- dt2$C2[id2]

然而,这似乎只是很少的代码行,特别是如果我有很多列。

我在想像

这样的东西
# Not working:
dt1[id1][,list(B,C)] <- dt2[id2][,list(B2,C2)]

会起作用,但我收到错误消息。

有更聪明,更好的方法吗?

1 个答案:

答案 0 :(得分:2)

我们可以加入on&#39; A&#39;用&#39; A2&#39;并将(:=)感兴趣的列的值分配给&#39; C&#39;和&#39; D&#39;

library(data.table)#v1.9.7+
dt1[dt2,  c('C', 'D') := .(C2, D2),  on = .(A= A2)]
dt1
#     A B C D
# 1:  1 1 2 3
# 2:  2 1 2 3
# 3:  3 1 2 3
# 4:  4 1 2 3
# 5:  5 1 5 6
# 6:  6 1 5 6
# 7:  7 1 5 6
# 8:  8 1 5 6
# 9:  9 1 5 6
#10: 10 1 2 3

如果我们需要更改许多列,而不是键入列,我们会使用values获取mget并将其分配到&#39; dt1&#中的相应列名称39;

dt1[dt2, names(dt1)[3:4] :=  mget(names(dt2)[3:4]), on = .(A = A2)]