data.table join然后将列添加到现有data.frame而不重新复制

时间:2013-10-23 21:53:36

标签: r join reference copy data.table

我有两个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中?

2 个答案:

答案 0 :(得分:26)

这很容易做到:

X[Y, z := i.z]

这是有效的,因为此处Y[X]X[Y]之间的唯一区别是,某些元素不在Y中,在这种情况下,您可能希望zNA,上述作业将完全按照这一点进行。

它对许多变量也同样有用:

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

由于您需要操作Y[X],您可以添加参数nomatch=0(如@mnel指出的那样),以便不为那些X不包含来自Y的键值的那些获取NA那就是:

X[Y, z := i.z, nomatch=0]

来自NEWS for data.table

    **********************************************
    **                                          **
    **   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