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
,在这种情况下你可能想要z
是NA
,而上面的分配恰好是这样做的。
这对许多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中数据框的行 。