【问题标题】:Replicate dplyr::left_join() column order with data.table x[y] syntax使用 data.table x[y] 语法复制 dplyr::left_join() 列顺序
【发布时间】:2021-05-21 15:56:48
【问题描述】:

由于性能提高,我将很多数据操作管道从 dplyr 切换到 data.table。我喜欢 a[b] 连接语法的简洁性。 dplyr::left_join(x, y) 对应于data.table 中的y[x]。但是,在这两种情况下,列顺序是不同的。有没有办法复制从 dplyr left_join 获得的列顺序,其中来自 y 的新列被添加到 x 的右侧,使用 data.table 的 y[x] 语法?我知道你可以使用merge(x, y, all.x = TRUE),但我很好奇[] 方式是否可以达到相同的效果。

示例

library(dplyr)
library(data.table)

x <- iris
y <- data.frame(Species = c('setosa', 'virginica'), foo = c(100, 200))

j1 <- left_join(x, y)

setDT(x)
setDT(y)

j2 <- y[x, on = 'Species']

j3 <- merge(x, y, all.x = TRUE)

如何使j2j1j3 具有相同的列顺序?

> head(j1, 1)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species foo
1:          5.1         3.5          1.4         0.2  setosa 100
> head(j2, 1)
   Species foo Sepal.Length Sepal.Width Petal.Length Petal.Width
1:  setosa 100          5.1         3.5          1.4         0.2
> head(j3, 1)
   Species Sepal.Length Sepal.Width Petal.Length Petal.Width foo
1:  setosa          5.1         3.5          1.4         0.2 100

【问题讨论】:

    标签: r dplyr data.table


    【解决方案1】:

    我们可以做一个作业 (:=),这会更有效,因为这是通过引用做的

    j2 <- copy(x)
    j2[y, foo := foo, on = .(Species)]
    

    -测试

    all.equal(j1, type.convert(as.data.frame(j2), as.is = TRUE))
    #[1] TRUE
    

    【讨论】:

    • 如果y 中有多个列而不是我们要加入的列,这是否需要您为所有列分配:=
    • @qdread 如果还有更多,例如foo1、foo2 等 nm1 &lt;- names(y)[3:5] ,然后是 j2[y, (nm1) := mget(nm1), on = .(Species)]
    • 或者如果是除'Species'以外的所有列,nm1 &lt;- setdiff(names(y), 'Species')然后应用相同的代码
    • 这是一个不错的答案,但最后我认为代码最终比merge() 方式更冗长,所以我可能会坚持下去!
    • @qdread 我会说:= 应该更快
    猜你喜欢
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多