R 如何执行data.table合并操作

R 如何执行data.table合并操作,r,merge,data.table,R,Merge,Data.table,注:此问题和以下答案涉及数据表版本x a b [1,] 1 2 [2,] 2 3 [3,] 3 4 >y y a c [1,1]a [2,]2b [3,]3 c >x[y] a b [1,] 1 2 [2,] 2 3 [3,] 3 4 >合并(x,y) a、b、c 1 12 a 2 3 b 3 3 4 c 文档中说:“当[第一个参数]本身是data.table时,将调用类似于base::merge的连接,但对排序键使用二进制搜索。”显然情况并非如此。我可以用data.tables将y中的其他列

注:此问题和以下答案涉及数据表版本<1.5.3;v1.5.3于2011年2月发布,以解决此问题。见最近的治疗(2012年3月):


我一直在翻阅文档(data.frame的替代品,在某些操作中效率更高),包括(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
>x
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
>y y
a c
[1,1]a
[2,]2b
[3,]3 c
>x[y]
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
>合并(x,y)
a、b、c
1 12 a
2 3 b
3 3 4 c

文档中说:“当[第一个参数]本身是data.table时,将调用类似于base::merge的连接,但对排序键使用二进制搜索。”显然情况并非如此。我可以用data.tables将y中的其他列放入x[y]的结果中吗?它似乎只是取了x的行,其中键与y的键匹配,但完全忽略了y的其余部分…

您引用的文档部分是错误的。如果您查看
[.data.table
的文档,您将看到:

当i是data.table时,x必须有一个 键,表示将i连接到x并返回 x中匹配的行。相等联接 在i中的每列之间执行 按顺序添加到x键中的每一列。 这与base R类似 子设置矩阵的功能 由2列矩阵和更高的 n维子集的维数 n列矩阵的数组

我承认包的描述(你引用的部分)有些混乱,因为它似乎说“[”-操作可以用来代替合并。但我认为它说的是:如果x和y都是数据表,我们在索引上使用连接(调用类似合并)而不是二进制搜索


还有一件事:

我通过
install.packages
安装的data.table库缺少
merge.data.table方法
,因此使用
merge
将调用
merge.data.frame
。安装R后,使用更快的
merge.data.table方法

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

methods(generic.function="merge")


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

我认为f3lix是正确的,文档有点误导。好处在于快速连接数据子集。之后您仍然需要像上面的示例一样使用
merge
函数

您将看到,他的示例是这样运行的。他首先对其中一个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')]
库(data.table)

sdt感谢您的回答。我在最初发布时错过了此线程。data.table从2月份开始移动。1.4.1不久前发布到CRAN,1.5即将发布。例如,DT()别名已替换为list();作为原语,它的速度要快得多,而data.table现在继承自data.frame,因此它可以与只接受data.frame的包(如ggplot和lattice)一起工作,而不需要任何转换(更快、更方便)

有没有可能订阅data.table标签,这样当有人发布带有该标签的问题时,我会收到一封电子邮件?datatable帮助列表已经增长到每月大约30-40条消息,但如果我能得到某种通知,我也很乐意在这里回答


Matthew

我认为不需要使用
base::merge
函数,因为使用
数据。表
连接可以快得多。例如,请参见以下内容。我制作了
x
y
数据表,其中包含3-3列:

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)
结果不完全相同,因为后者有一个额外的列:

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

这不会造成太大的麻烦:)

啊。看起来CRAN上的版本是1.2版,而R-Forge上的版本是1.3版。显然,
merge
方法是在1.3中添加的。从我在R-Forge周围看到的情况来看,该方法是在大约8个月前添加的,所以我不知道为什么它还没有在CRAN上!X[Y]语法在2011年2月发布到CRAN的v1.5.3版本中发生了更改。请查看新闻、新的?data.table和更正的常见问题解答。谢谢,这很有趣。不过,这是一个完全不明显的语法!如果我使用它,我可能会重新定义一个函数,该函数具有
函数(x,y)x[,列表(x,y)]
或其他什么,可能也会删除额外的键列……我认为data.table中连接的正确语法实际上是x[y]或x[y,],即连接应该使用第一个索引。这会给出与merge相同的结果。请注意,x[y]和y[x]不需要完全相同,即,如果y在foo中包含不代表x的条目。可能我遗漏了一些内容,但请参见数据表中的连接。上面的x[,list(x,y)]对我不起作用。我尝试了x[,c(x,y)],但它起了作用。我不确定这是否有意义。使用setkey后,您可以只执行x[y]2011年2月发布给CRAN的v1.5.3解决了这一问题。请查看其新闻、新数据表和更正的常见问题解答。
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