我试图从文档中了解data.table
中的逻辑,有点不清楚。我知道我可以尝试这个,看看会发生什么,但我想确保没有病态的情况,因此想知道逻辑是如何实际编码的。如果两个data.table
个对象具有不同数量的键列,例如a
有2个而b
有3个,而您运行c <- a[b]
,则a
和只需在前两个键列上合并b
,或者将{3}中的第三列自动合并到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
中的id
键列匹配的b
行。例如,对于id==1
中的b
,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)))
。
答案 0 :(得分:7)
好问题。首先,正确的术语是(来自?data.table
):
[a data.table]可能包含一个或多个列的一个键 。此键可用于行索引而不是rownames。
所以“关键”(单数)不是“关键”(复数)。目前,我们可以使用“钥匙”。但是,如果将来添加辅助密钥,则然后可以是多个密钥。每个键(单数)可以有多个列(复数)。
否则你绝对正确。基于其他人的反馈,以下段落在v1.8.2中得到了改进。来自?data.table
:
当我是data.table时,x必须有一个键。我使用x的键加入x,并返回匹配的x行。在i的每一列之间执行等连接到x的键中的每一列;即,i的第1列与x的第1列匹配,第2列与第2列匹配,等等。匹配是在O(log n)时间内编译的C中的二进制搜索。如果我的列少于x的键,则x的多行通常与i的每一行匹配,因为不是所有x的键列都将连接到(一个常见的用例)。如果我有比x的键更多的列,则不参与连接的i列将包含在结果中。如果我也有一个密钥,那么i是用于匹配x的密钥列的密钥列(i的密钥的第1列连接到x的密钥的第1列,第2列连接到第2列,依此类推)和二进制合并这两个表的执行情况。在所有连接中,列的名称无关紧要。 x键的列按顺序连接,从i的第1列开始,当我未键入时,或者从i的键的第1列开始。
以下评论,在v1.8.3(关于R-Forge)中,现在读取(以粗体显示):
当我是data.table时,x必须有一个键。我使用x的键加入x,并返回匹配的x行。在i的每一列之间执行等连接到x的键中的每一列;即,i的第1列与x的第1列匹配,第2列与第2列匹配,等等。匹配是在O(log n)时间内编译的C中的二进制搜索。如果我的列少于x的键,那么并非x的所有键列都将被连接到(一个常见的用例),并且x的许多行将(通常)与i的每一行匹配。如果我有比x的键更多的列,则不参与连接的i列将包含在结果中。如果我也有一个键,那么i是用于匹配x的键列的键列(i的键的第1列连接到x的键的第1列,第i列的第2列是x键的第2列,等等,只要更短的密钥)和两个表的二进制合并就可以执行。在所有联接中,列的名称无关紧要; x键的列按顺序连接,从i的第1列开始,当我未键入时,或者从i的键的第1列开始。 在代码中,连接列的数量由min(length(key(x)),if(haskey(i))length(key(i))else ncol(i)确定。 < / p>
答案 1 :(得分:0)
引用data.table FAQ:
X [Y]是一个连接,使用Y(或Y的键,如果有的话)作为索引查找X的行。 Y [X]是一个连接,使用X(或X的键,如果有的话)作为索引查找Y的行。 merge(X,Y)同时执行两种方式。 X [Y]和Y [X]的行数通常不同; 而merge(X,Y)和merge(Y,X)返回的行数相同。