我试图从文档中理解data.table
中的逻辑,但有点不清楚。我知道我可以尝试一下,看看会发生什么,但我想确保没有病理病例,因此我想知道逻辑实际上是如何编码的。当两个data.table
对象具有不同数量的键列时,例如a
有2个,b
有3个,并且您运行c <- a[b]
,a
和b
会简单地合并在前两个键列上,还是会将a中的第三列自动合并到b
中的第三键列?一个例子:
require(data.table)
a <- data.table(id=1:10, t=1:20, v=1:40, key=c("id", "t"))
b <- data.table(id=1:10, v2=1:20, key="id")
c <- a[b]
这应该选择a
中与b
中的id
键列匹配的行。例如,对于b
中的id==1
,b
中有2行,a
中有4行应在c
中生成8行。事实似乎就是这样:
> head(c,10)
id t v v2
1: 1 1 1 1
2: 1 1 21 1
3: 1 11 11 1
4: 1 11 31 1
5: 1 1 1 11
6: 1 1 21 11
7: 1 11 11 11
8: 1 11 31 11
9: 2 2 2 2
10: 2 2 22 2
另一种尝试方法是:
d <-b[a]
这应该做同样的事情:对于a
中的每一行,它应该选择b
中的匹配行:由于a
有一个额外的键列t
,所以该列不应该用于匹配,并且应该只基于第一个键列进行连接,id
应该完成。情况似乎是这样的:
> head(d,10)
id v2 t v
1: 1 1 1 1
2: 1 11 1 1
3: 1 1 1 21
4: 1 11 1 21
5: 1 1 11 11
6: 1 11 11 11
7: 1 1 11 31
8: 1 11 11 31
9: 2 2 2 2
10: 2 12 2 2
有人能确认吗?需要明确的是:a
的第三个键列是否在任何合并中使用过,或者data.table
是否只使用了两个表中的min(length(key(DT)))
。
好问题。首先,正确的术语是(来自?data.table
):
[A data.table]可能具有一个或多个列的一个键。此键可用于行索引而不是行名。
所以"key"(单数)而不是"keys"(复数)。目前,我们可以用"钥匙"逃脱惩罚。但是,当将来添加辅助密钥时,可能会有,然后会有多个密钥。每个键(单数)可以有多个列[/em>(复数)。
否则你是绝对正确的。在v1.8.2中,根据其他人的反馈对以下段落进行了改进。来自?data.table
:
当i是data.table时,x必须有一个键。使用x的键将i连接到x,并返回x中匹配的行。i中的每一列与x的键中的每列之间执行等连接;即,i的第1列与x的键的第一列匹配,第2列与第二列匹配,等等。该匹配是在O(logn)时间内编译的C中的二进制搜索。如果i的列比x的键少,那么x的许多行通常会与i的每一行匹配,因为并非所有x的键列都会连接到(这是一种常见的用例)。如果i的列数多于x的键,则未参与联接的i的列将包含在结果中。如果我也有一个键,则是i的键列用于匹配x的键列(i的键的第1列与x的键的第一列相连,第2列与第2列相连,依此类推),并执行两个表的二进制合并。在所有联接中,列的名称都是不相关的。x的键的列按顺序连接,或者从i的第1列开始(当i被解锁时),或者从第1列起(从i的键开始)。
以下评论,在v1.8.3(在R-Forge上)中,现在读取(粗体更改):
当i是data.table时,x必须有一个键。使用x的键将i连接到x,并返回x中匹配的行。i中的每一列与x的键中的每列之间执行等连接;即,i的第1列与x的键的第一列匹配,第2列与第二列匹配,等等。该匹配是在O(logn)时间内编译的C中的二进制搜索。如果i的列比x的键少,那么并不是所有x的键列都会连接到(一个常见的用例),并且x的许多行(通常)会与i的每一行匹配。如果我也有一个键,则用于匹配x的键列的是i的键列(i的键的第1列与x的键的第一列相连,i的键第2列与x键的第2列相连,依此类推,只要键较短),并执行两个表的二进制合并。在所有联接中,列的名称都是不相关的;x的键的列按顺序连接,或者从i的第1列开始(当我被解锁时),或者从我的键的第1行开始在代码中,联接列的数量由min(length(key(x))、if(haskey(i))length(keyi)else-ncol(i)决定
报价数据表常见问题解答:
X[Y]是一个联接,使用Y(或Y的键,如果有)作为索引查找X的行。Y[X]是一个联接,使用X(或X的键,如果有)作为索引查找Y的行。merge(X,Y)同时执行两种操作。X[Y]和Y[X]的行数通常不同;而merge(X,Y)和merge(Y,X)返回的行数是相同的。