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

Ari*_*man 19 join copy r reference 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" )
Run Code Online (Sandbox Code Playgroud)

我想在X上做一个左外连接,我可以做到Y[X]这一点,感谢:

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

但我想在X 复制的情况下添加新列X(因为它很大).

显然,像X <- Y[X]作品这样的东西,但除非data.table比我给它的功劳更加明确(并且我非常狡猾地给予它赞美!),我相信这复制了整个X.

X[ , z:= Y[X,z]$z ] 虽然工作正常,但却不能很好地扩展到多个列.

如何将合并的结果以有效的方式(在副本方面和程序员时间方面)存储回保留的data.table中?

edd*_*ddi 27

这很容易做到:

X[Y, z := i.z]
Run Code Online (Sandbox Code Playgroud)

它的工作原理,因为之间的唯一区别Y[X],并X[Y]在这里,是当一些元件不Y,在这种情况下,可能你会想zNA,它上面的分配将究竟.

它也适用于许多变量:

X[Y, `:=`(z1 = i.z1, z2 = i.z2, ...)]
Run Code Online (Sandbox Code Playgroud)

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

X[Y, z := i.z, nomatch=0]
Run Code Online (Sandbox Code Playgroud)

来自NEWS的data.table

    **********************************************
    **                                          **
    **   CHANGES IN DATA.TABLE VERSION 1.7.10   **
    **                                          **
    **********************************************
Run Code Online (Sandbox Code Playgroud)

新功能

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.
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢.这是有效的(即使我编辑的示例数据),但我不明白为什么.是否有"i.符号"的名称?我在`?[.data.table`中找不到它. (4认同)
  • 我认为`i.用法很难记录,我忘记了它现在的位置 - 但它只是用于引用`i-expression` data.table的列 (3认同)
  • @ AriB.Friedman - 它是1.7S版本的新闻(我添加了一个链接).对于差异,它归结为你不能通过引用添加行(但),所以`X [Y,z:= iz]`将相当于设置`z = iz` X [Y,z := iz,nomatch = 0]` (2认同)

Ale*_* Li 6

作为上述答案的补充,您还可以执行(v1.9.6+):

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

where colNames是一个列出所需列的字符向量Y.这使您可以在添加许多列的情况下有效地选择要添加的列(colNames从子集中定义names(Y)).

此外,您可以将它与新on=参数(from 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"]
Run Code Online (Sandbox Code Playgroud)

(colNames) := mget(colNames)这里的策略归功于akrun :更新R中的数据帧行.

  • 实际上不是 akrun,而是上面你在这里介绍的那个人:/sf/answers/2132888271/。所以基本上这个线程上的两个答案都是eddi的 (2认同)