我有两个data.tables
,X(3米行乘500列)和Y(100行乘两列)。
set.seed(1)
X <- data.table( a=letters, b=letters, c=letters, g=sample(c(1:5,7),length(letters),replace=TRUE), key="g" )
Y <- data.table( z=runif(6), g=1:6, key="g" )
我想在X上进行左外连接,我可以Y[X]
执行此操作,这要归功于:
Why does X[Y] join of data.tables not allow a full outer join, or a left join?
但我想将新列添加到X
而不复制X
(因为它很大)。
显然,像X <- Y[X]
这样的东西有效,但是除非data.table
远远超过我认可的(并且我认为它非常狡猾!),我相信这会复制整个X
。
X[ , z:= Y[X,z]$z ]
可以使用,但是很难克服并且不能很好地扩展到多个列。
如何以合法的方式(在副本和程序员时间方面)将合并结果存储回保留的data.table中?
答案 0 :(得分:26)
这很容易做到:
X[Y, z := i.z]
这是有效的,因为此处Y[X]
和X[Y]
之间的唯一区别是,某些元素不在Y
中,在这种情况下,您可能希望z
是NA
,上述作业将完全按照这一点进行。
它对许多变量也同样有用:
X[Y, `:=`(z1 = i.z1, z2 = i.z2, ...)]
由于您需要操作Y[X]
,您可以添加参数nomatch=0
(如@mnel指出的那样),以便不为那些X不包含来自Y的键值的那些获取NA那就是:
X[Y, z := i.z, nomatch=0]
********************************************** ** ** ** CHANGES IN DATA.TABLE VERSION 1.7.10 ** ** ** **********************************************
新功能
o The prefix i. can now be used in j to refer to join inherited columns of i that are otherwise masked by columns in x with the same name.
答案 1 :(得分:6)
作为上述答案的补充,您还可以执行(v1.9.6+
):
require(data.table) # v1.9.6+
X[Y, (colNames) := mget(paste0("i.", colNames))]
其中colNames
是一个字符向量,列出了您想要的列Y
。这使您可以在添加多列的情况下有效地选择要添加的列(从colNames
的子集中定义names(Y)
)。
此外,您可以将其与新的on=
参数(来自v1.9.6+
)合并为:
# ad-hoc joins using 'on=' instead of setting keys
require(data.table) # v1.9.6+
X[Y, (colNames) := mget(paste0("i.", colNames)), on = "g"]
此处(colNames) := mget(colNames)
策略归功于akrun:Update rows of data frame in R。