为了账号安全,请及时绑定邮箱和手机立即绑定

data.table连接,然后将列添加到现有的data.frame中,而无需重新复制

data.table连接,然后将列添加到现有的data.frame中,而无需重新复制

海绵宝宝撒 2019-12-04 12:46:42
我有两个data.tables,X(3m行,约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]要归功于:为什么data.tables的X [Y]联接不允许完全外部联接或左联接?但是我想添加新列X 而不进行复制X(因为它很大)。显然,类似的东西很X <- Y[X]有效,但除非data.table比我认为它聪明得多(而且我认为它有很多曲折!),否则我相信它会复制整个X。X[ , z:= Y[X,z]$z ] 可以,但是很笨拙,无法很好地扩展到不止一列。如何以有效的方式(无论是在副本方面还是在程序员时间方面)将合并结果存储回保留的data.table中?
查看完整描述

2 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

这很容易做到:


X[Y, z := i.z]

之所以起作用,是因为Y[X]和之间的唯一区别X[Y]是当某些元素不在in时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]

从NEWS获取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.


查看完整回答
反对 回复 2019-12-04
?
呼如林

TA贡献1798条经验 获得超3个赞

除了上述答案外,您还可以执行(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的策略:更新R中的数据帧行。


查看完整回答
反对 回复 2019-12-04
  • 2 回答
  • 0 关注
  • 592 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信