data.table连接然后添加列到现有data.frame没有重新复制

我有两个data.tables ,X(3行data.tables列)和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]来完成,这要归功于:

为什么data.tables的X [Y]连接不允许完整的外连接或左连接?

但是我想添加新的列到X 而不复制X (因为它是巨大的)。

很显然,像X <- Y[X]这样的东西是有效的,但是除非data.table远远超过我所称赞的(而且我相当相当多的歪曲!),我相信这会复制整个X

X[ , z:= Y[X,z]$z ]可以工作,但是非常好,不能很好地扩展到多个列。

如何以合理的方式将合并结果存储到保留的data.table中(无论是在副本方面还是在程序员时间方面)?

这很容易做到:

 X[Y, z := iz] 

这是有效的,因为Y[X]X[Y]之间的唯一区别就是当某些元素不在Y ,在这种情况下你可能想要zNA ,而上面的分配恰好是这样做的。

这对许多variables也同样适用:

 X[Y, `:=`(z1 = i.z1, z2 = i.z2, ...)] 

由于您需要Y[X]操作,所以您可以添加参数nomatch=0 (如@mnel指出的那样),以便对于X不包含来自Y的键值的那些参数不会获得NAs。即:

 X[Y, z := iz, nomatch=0] 

从新闻data.table

  ********************************************** ** ** ** CHANGES IN DATA.TABLE VERSION 1.7.10 ** ** ** ********************************************** 

新function

 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. 

除了上面的答案之外,你也可以做( v1.9.6+ ):

 require(data.table) # v1.9.6+ X[Y, (colNames) := mget(paste0("i.", colNames))] 

colNames是一个字符向量,列出了你想从Y得到的列。 这使您可以有效地select要添加的列(在names(Y)的子集names(Y)定义colNames ),以便添加多个列。

另外,您可以将它与新的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)(colNames) := mget(colNames)策略: 更新R中数据框的行 。