9

我试图data.table从文档中理解逻辑并且有点不清楚。我知道我可以试试这个看看会发生什么,但我想确保没有病态的情况,因此想知道逻辑是如何实际编码的。当两个data.table对象具有不同数量的键列时,例如a有 2 和b3,并且您运行c <- a[b], 将简单ab合并在前两个键列上,或者将 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匹配的行。例如,对于in ,有 2 行 in和 4 行应该在 中生成 8 行。这确实是似乎发生的事情:idbid==1bbac

> 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)))两个表中的。

4

2 回答 2

7

好问题。首先正确的术语是(来自?data.table):

[A data.table] 可能有一个或多个列的一个键。此键可用于行索引而不是行名。

所以“key”(单数)不是“keys”(复数)。目前,我们可以摆脱“钥匙”。但是当将来添加辅助键时,可能会有多个键。每个(单数)可以有多个(复数)。

否则你是绝对正确的。根据其他人的反馈,以下段落在 v1.8.2 中进行了改进。来自?data.table

当 i 是 data.table 时,x 必须有一个键。i 使用 x 的键连接到 x,并返回 x 中匹配的行。在 i 中的每一列与 x 的键中的每一列之间执行 equi-join;即,i 的第 1 列与 x 的键的第 1 列匹配,第 2 列与第 2 列匹配,依此类推。匹配是在 O(log n) 时间内编译的 C 中的二进制搜索。如果 i 的列少于 x 的键,则 x 的许多行通常会匹配 i 的每一行,因为并非 x 的所有键列都将连接到(常见用例)。如果 i 的列多于 x 的键,则 i 中未参与连接的列将包含在结果中。如果 i 也有一个键,则 i 的键列用于匹配 x 的键列(i 的键的第 1 列连接到 x 的键的第 1 列,第 2 列到第 2 列,依此类推)并执行两个表的二进制合并。在所有连接中,列的名称是不相关的。x 的键的列按顺序连接,当 i 未键入时从 i 的第 1 列开始,或者从 i 的键的第 1 列开始。


根据评论,在 v1.8.3(在 R-Forge 上)中,现在显示为(更改为粗体):

当 i 是 data.table 时,x 必须有一个键。i 使用 x 的键连接到 x,并返回 x 中匹配的行。在 i 中的每一列与 x 的键中的每一列之间执行 equi-join;即,i 的第 1 列与 x 的键的第 1 列匹配,第 2 列与第 2 列匹配,依此类推。匹配是在 O(log n) 时间内编译的 C 中的二进制搜索。如果 i 的列少于 x 的键,则并非所有 x 的键列都将连接到(常见用例),并且 x 的许多行将(通常)与 i 的每一行匹配。如果 i 的列多于 x 的键,则 i 中未参与连接的列将包含在结果中。如果 i 也有一个键,则 i 的键列用于匹配 x 的键列(i 的键的第 1 列连接到 x 的键的第 1 列,i 的 key 的第 2 列到 x 的 key 的第 2 列,以此类推,只要较短的 key ) 并执行两个表的二进制合并。在所有连接中,列的名称是不相关的;x 的键的列按顺序连接,当 i 未键入时从 i 的第 1 列开始,或者从 i 的键的第 1 列开始。在代码中,连接列的数量由 min(length(key(x)),if (haskey(i)) length(key(i)) else ncol(i)) 决定。

于 2012-10-16T19:41:35.963 回答
0

引用 data.table常见问题

X[Y] 是一个连接,使用 Y(或 Y 的键,如果有的话)作为索引来查找 X 的行。Y[X] 是一个连接,使用 X(或 X 的键,如果有的话)作为索引来查找 Y 的行。merge(X,Y) 同时做这两种方式。X[Y] 和 Y[X] 的行数通常不同;而 merge(X,Y) 和 merge(Y,X) 返回的行数是相同的。

于 2012-10-16T19:32:55.437 回答