Hel*_*len 5 r left-join dplyr data.table
我想知道为什么 data.table 的左连接没有给我多个匹配项,似乎有一些奇怪的内置“无重复”,这并不能真正使其成为左连接,不是吗?
数据:
test=data.table(mtcars[1,])
test2=data.table(mtcars[c(1,1),])
Run Code Online (Sandbox Code Playgroud)
数据表:
test[test2, on = c(carb = "carb"), wt2 := i.wt]
Run Code Online (Sandbox Code Playgroud)
dplyr:
test %>% left_join(test2 %>% select(carb, wt) %>% rename(wt2 = wt),
by = "carb")
Run Code Online (Sandbox Code Playgroud)
dplyr 给了我正确的两行结果,但 data.table 只给了我一行。这里发生了什么?
在这里参考@Frank的答案:\n左连接(一列)首选哪种 data.table 语法
\n,以及 @Jaap 的答案:\n使用 data.table 进行左连接
\n我认为对于真正寻求左连接并来到这个社区寻求答案的人来说,这是一个危险的领域。链接中提供的参考示例更新(使用 的解决方案:=)(此处 OP 使用的方法相同)并不是真正的左连接。左连接返回左表中的所有记录,以及右表中的匹配记录,但data.table我们正在讨论的这种语法实际上并不返回右表中的所有匹配记录,因此不是左连接。
data.table 文档明确指出左连接是:
\nX[DT, on="x"] # left join\nRun Code Online (Sandbox Code Playgroud)\n,这将使正确的 data.table OP 正在查找:
\ntest[test2, on="carb"] # or,\ntest[test2[, wt2 := wt][,c("carb", "wt2")], on="carb"] # left join\nRun Code Online (Sandbox Code Playgroud)\n:=@Jaap 在他的回答中解释了通过引用连接(使用符号)和常规左连接之间的区别:
\n\n虽然这对于像这样的小数据集来说没有明显的区别,但它确实对 data.table 设计的大型数据集产生了影响。
\n
在我看来,这里有两个说法很可怕。一是结果确实存在明显的差异,因为使用两种方法的结果是不同的(尽管我理解他在谈论速度,编辑:正如@jangorecki指出的那样,这与速度无关,而是与内存使用有关。通过引用更新不会在内存中创建第二个对象)。第二件事是假设(在我看来,恭敬地)是,如果一个人正在处理大型数据集并且意图是进行左连接,那么我从来没有人不希望右表中的所有匹配项。
\n我\xe2\x80\x99m 不知道如何使用\xe2\x80\x98data.table\xe2\x80\x99 中的引用更新来实际执行左连接。我的推理是它:=被定义为仅在 j 中使用(data.table语法)。它通过引用添加、更新或删除列。它根本不复制内存的任何部分。但是,由于如果我们在右表中获得多个匹配项(如果我们打算进行实际的左连接),我们可能必须向左表添加额外的行,因此 si don\xe2\x80\x99t 认为可以:=使用该运算符,因为它适用于列