笔记:这个问题和以下答案参考data.table版本<1.5.3;v.2011 年 2 月发布了 1.5.3 来解决此问题。 查看最近的治疗(03-2012): 将外键上的 SQL 连接转换为 R data.table 语法


我一直在挖掘文档 数据表包 (data.frame 的替代品,对于某些操作来说效率更高),包括 Josh Reich 在 NYC R Meetup 上关于 SQL 和 data.table 的演讲 (pdf),但无法弄清楚这个完全微不足道的操作。

> x <- DT(a=1:3, b=2:4, key='a')
> x
     a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> y <- DT(a=1:3, c=c('a','b','c'), key='a')
> y
     a c
[1,] 1 a
[2,] 2 b
[3,] 3 c
> x[y]
     a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> merge(x,y)
  a b c
1 1 2 a
2 2 3 b
3 3 4 c

文档说:“当[第一个参数]本身是一个数据时。显然不是这样。我可以使用 data.tables 将 y 中的其他列获取到 x[y] 的结果中吗?看起来它只是获取 x 的行,其中键与 y 的键匹配,但完全忽略 y 的其余部分......

有帮助吗?

解决方案

您引用了文档的错误部分。如果你看一下文档 [.data.table 你会读到:

当我是一个数据时。表,x必须有一个键,这意味着将i加入x和x和 返回x中的行. 。按顺序,在X键中的每一列中的每列中的每一列之间执行一个等电量。这类似于通过2列矩阵设置矩阵的基础R功能,在更高的维度下,通过n列矩阵来子集n维数组

我承认包的描述(你引用的部分)有点令人困惑,因为它似乎说可以使用“[”操作来代替合并。但我认为它说的是:如果 x 和 y 都是 data.tables,我们在索引上使用联接(像合并一样调用)而不是二分搜索。


还有一件事:

我通过安装的 data.table 库 install.packages 缺少了 merge.data.table method, ,所以使用 merge 会打电话 merge.data.frame. 。安装后 R-Forge 的软件包 R用得更快 merge.data.table 方法。

您可以通过检查以下输出来检查是否有 merge.data.table 方法:

methods(generic.function="merge")

编辑[答案不再有效]: 这个答案指的是data.table版本1.3。在版本 1.5.3 中,data.table 的行为发生了变化,x[y] 返回了预期的结果。谢谢 马修·道尔, data.table 的作者,在评论中指出了这一点。

其他提示

感谢您的回答。当它最初发布时我错过了这个线程。data.table 自二月份以来一直在变化。1.4.1 不久前发布到 CRAN,1.5 也即将发布。例如,DT() 别名已替换为 list();作为一个原语,它的速度要快得多,并且 data.table 现在继承自 data.frame,因此它可以与以下包一起使用 仅有的 接受ggplot和lattice等data.frame,无需任何转换(更快更方便)。

是否可以订阅 data.table 标签,以便当有人用该标签发布问题时我会收到一封电子邮件?数据表帮助列表已增长到每月约 30-40 条消息,但如果我能收到某种通知,我也很乐意在这里回答。

马修

我认为使用 base::merge 不需要函数,因为使用 data.table 连接可以快得多。例如。请参阅以下内容。我做 xy 具有 3-3 列的 data.tables:

x <- data.table( foo = 1:5, a=20:24, zoo = 5:1 )
y <- data.table( foo = 1:5, b=30:34, boo = 10:14)
setkey(x, foo)
setkey(y, foo)

并将两者合并 base:mergedata.table 加入以查看执行速度:

system.time(merge(x,y))
##    user  system elapsed 
##   0.027   0.000   0.023 

system.time(x[,list(y,x)])
##    user  system elapsed 
##   0.003   0.000   0.006 

结果并不相同,因为后者多了一个列:

merge(x,y)
##      foo  a zoo  b boo
## [1,]   1 20   5 30  10
## [2,]   2 21   4 31  11
## [3,]   3 22   3 32  12
## [4,]   4 23   2 33  13
## [5,]   5 24   1 34  14

x[,list(x,y)]
##      foo  a zoo foo.1  b boo
## [1,]   1 20   5     1 30  10
## [2,]   2 21   4     2 31  11
## [3,]   3 22   3     3 32  12
## [4,]   4 23   2     4 33  13
## [5,]   5 24   1     5 34  14

这不会造成大麻烦:)

我认为 f3lix 是正确的,并且文档有点误导。这样做的好处是可以快速连接来对数据进行子集化。您最终仍然需要使用 merge 之后的功能如上面的示例所示。

你会看到在 Josh 关于使用 data.table 的演示 这就是他的例子的运行方式。他首先对其中一个 data.tables 进行子集化,然后进行合并:

library(data.table)
sdt <- DT(series, key='series_id')
ddt <- DT(data, key='series_id')
u <- sdt[ grepl('^[A-Z]{2}URN', fred_id) & !grepl('DSURN', fred_id) ]
d <- ddt[ u, DT(min=min(value)), by='series_id', mult='all']
data <- merge(d,series)[,c('title','min','mean','max')]
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top