问题 外联接data.table R.


只是想知道是否有一种有效的方法来与数据表进行外连接,例如

a <- data.table(a=c(1,2,3),b=c(3,4,5))
b <- data.table(a=c(1,2),k=c(1,2))
merge(a,b,by="a",all.x=T)

这样可以正常工作,但它没有内部连接那么高效,因为下面的运行速度非常快,但上面的速度非常慢。

setkey(a,a)
setkey(b,a)
a[b,]

3567
2017-11-21 12:20


起源

在第一种情况下, a 和 b 是这样的 merge 将需要首先键入它们(作为本地副本(种类)在merge中,因为它不想更改 a 和 b 在调用范围)。在第二种情况下,你很乐意改变 a 和 b 通过键入它们(你是否包括时间来做那个?)然后 a[b] 很快但即使如此,我也感到惊讶,这是一个很大的不同。 merge  应该 相当于 x[y]。在谈到时间时请说明版本信息:你是否在v1.8.6?而且你的“非常快”和“非常慢”可能是我“相似”的想法!什么是实际时间? - Matt Dowle
严重/不恰当地进行基准测试非常容易,所以我们肯定需要先查看您的计时方法,然后再说些什么。 - Matt Dowle
我无法为此提供时间,因为第一个在记忆中爆炸并且坠毁了R会话(加入了大约1900行)。我将用较小的一组对其进行基准测试并发布结果。 (版本1.8.2,我正在使用) - jamborta
这对于较小的一组来说会很棒。我们经常看到用户报告 merge 当意外请求笛卡尔连接时,爆炸(基本合并以及data.table合并)。也许我们可以在那里放一些陷阱来帮助检测和捕获错误的用法。只是一个猜测。似乎人们有时会尝试使用 merge 他们真正需要的时候 cbind。 - Matt Dowle


答案:


b[a,] 是你正在寻找的“外部联接”。

看一眼 ?merge.data.table 更多具体细节。


10
2017-11-21 13:28



谢谢!所以a [b,]或b [a,]本质上是左连接(用SQL术语)?我一直认为这是一个内心的联系。 - jamborta
@jamborta见常见问题解答2.16(nomatch = 0|NA) - Matt Dowle
谢谢马修,这解释了它。我假设这种方式你不能做完全外连接(只剩下外部和内部)? - jamborta
@jamborta正确。但你可以做到 X[Y] 要么 Y[X] 左或右。它来源于 通过,而无需逐 功能(类似于SQL中的CROSS APPLY和OUTER APPLY)。这个想法就是这样 j 运行每一行 i。这在完全外连接上下文中没有意义。如果需要完全外连接那么那就是 merge 可以做。话虽如此,它已经出现,并且已经请求了更多的连接类型 在这个详细的问题,这是在列表中考虑。 - Matt Dowle