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

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


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

> 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.table时,会调用一个类似于base :: merge的连接,但在已排序的键上使用二进制搜索。” 显然情况并非如此。 我可以通过data.tables将y中的其他列转换为x [y]的结果吗? 看起来好像只是将x的行匹配到y的关键字,但完全忽略y的其余部分...


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

当我是一个data.table时,x必须有一个键,意思是将我连接到x并返回匹配的x中的行 。 按顺序在i中的每列与x的键中的每列之间执行等连接。 这类似于通过2列矩阵对子矩阵进行子设置的基本R功能,并且在更高维中通过n列矩阵对n维阵列进行子集化

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


还有一件事:

我通过install.packages安装的data.table库缺少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的作者Matthew Dowle在评论中指出了这一点。


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

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

马修


我认为使用base::merge函数是不需要的,因为使用data.table连接可以快得多。 例如看下面的内容。 我用3-3列制作xy 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

这不能造成很大的麻烦:)

链接地址: http://www.djcxy.com/p/24901.html

上一篇: How to do a data.table merge operation

下一篇: What is difference between dataframe and list in R?