如何做一个data.table合并操作

注意:这个问题和下面的答案引用data.table版本<1.5.3; v。1.5.3于2011年2月发布解决此问题。 查看更多最近的处理(03-2012): 将外键上的SQL连接转换为R data.table语法


我一直在挖掘data.table包的文档(replacedata.frame,这对于某些操作来说效率更高),包括Josh Reich在NYC R Meetup (pdf) 上对SQL和data.table的介绍 ,但是不能把这个完全无关的操作算出来。

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

该文档说:“当[第一个参数]本身是一个data.table,一个连接被调用类似于base :: merge,但使用二进制searchsorting的关键。 显然情况并非如此。 我可以通过data.tables将y中的其他列转换为x [y]的结果吗? 它似乎只是把x的行匹配到y的关键字,而忽略y的其余部分…

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

当我是一个data.table,x必须有一个键,意思是把我连接到x并返回匹配的x中的行 。 按顺序在x的每一列中的每列之间执行一个等连接。 这类似于通过2列matrix来设置matrix的基本Rfunction,并且在更高维度上通过n列matrix来对n维arrays进行子集化

我承认这个包的描述(你引用的部分)有些令人困惑,因为它似乎是说“[”-operation可以用来代替合并。 但我认为它是这样说的:如果x和y都是data.tables,我们使用一个索引(这是像合并调用),而不是二进制search连接。


还有一件事:

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

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

 methods(generic.function="merge") 

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

感谢您的答案。 最初发布时,我错过了这个线程。 data.table已经从二月份开始。 1.4.1刚刚发布到CRAN,1.5版即将发布。 例如,DT()别名已被replace为list(); 作为一个原语它快得多,data.table现在inheritance自data.frame,因此它可以与接受data.frame(如ggplot和lattice)的包一起工作,而无需任何转换(更快,更方便)。

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

马修

我认为使用base::merge函数是不需要的,因为使用data.table连接可以快得多。 例如看下面的内容。 我使用3-3列创buildxy 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是正确的,文件是有点误导。 好处是快速join数据子集。 在上面的例子中,你最终还是需要使用merge函数。

你会在Josh的演示中看到使用data.table ,这是他的例子运行。 他首先将data.tables中的一个子集合起来,然后进行合并:

 library(data.table) sdt <- DT(series, key='series_id') ddt <- DT(data, key='series_id') u <- sdt[ grepl('^[AZ]{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')]