r - 如何(有效地)在 R 中连接具有多个主键的表?

标签 r join dplyr tidyverse

我对 R 中的 dplyr 包中的加入有一个小问题。我有 2 个(大)数据帧,我想加入。它们有多个共同的列,但一个足以连接它们。现在我做这样的事情:

tab1 <- data.frame(id= c("a", "b", "c", "d"),
                   name = c("Mike", "Anna", "John", "Edward"),
                   score = c(10, 20, 30, 20)
tab2 <- data.frame(id= c("a", "b", "c", "d"),
                   name = c("Mike", "Anna", "John", "Edward"),
                   color = c("red", "blue", "blue", "orange")
dplyr::left_join(x, y)

这个解决方案没问题,但您可以看到连接使用 idname 作为键,即使我们不需要两者。我担心的是,由于我使用更大的数据框并且我必须通过多次迭代来完成此操作,所以使用所有同名列将花费无用的时间。

我当然可以指定 by = id,但是 left_join 将保留 name.x 和 name.y。

所以我有两个问题:

  1. 使用多个键(比如 20 个键)的连接是否比使用一个键的连接花费更多时间?
  2. 如果答案是肯定的,是否有一种简单的方法来指定一个键并从一个表中删除其他重复的列?

我希望我的问题很清楚,不要犹豫,询问精确度,非常感谢!

最佳答案

关于你的第二个问题。您可以使用 suffix 为重复的列添加后缀,以便在连接后可以轻松删除它们。

为了回答您的第一个问题,我们可以对不同的选项进行基准测试。由于您关心效率,我还将 dplyr::left_join 与使用 merge 的基本 R 方法进行了比较,后者为我们提供了四个选项

  1. left_join 所有关键列
  2. left_join 一键+去除重复项
  3. 合并所有关键列
  4. 一键合并 + 去除重复项

根据我对您的示例数据的基准测试,所有键的 left_join 比一个键连接然后删除重复项更快。但是,如果您关心效率,我建议您查看 merge

library(dplyr)

tab1 <- data.frame(
  id = c("a", "b", "c", "d"),
  name = c("Mike", "Anna", "John", "Edward"),
  score = c(10, 20, 30, 20)
)
tab2 <- data.frame(
  id = c("a", "b", "c", "d"),
  name = c("Mike", "Anna", "John", "Edward"),
  color = c("red", "blue", "blue", "orange")
)
dplyr::left_join(tab1, tab2)
#> Joining, by = c("id", "name")
#>   id   name score  color
#> 1  a   Mike    10    red
#> 2  b   Anna    20   blue
#> 3  c   John    30   blue
#> 4  d Edward    20 orange

f1 <- function() left_join(tab1, tab2) 
f2 <- function() { 
  left_join(tab1, tab2, by = "id", suffix = c("", "_drop")) %>% 
    select(-ends_with("_drop")) 
}
f3 <- function() merge(tab1, tab2, by = c("id", "name"), all.x = TRUE)
f4 <- function() { 
  x <- merge(tab1, tab2, by = "id", all.x = TRUE, suffix = c("", "_drop"))
  x[, names(x)[!grepl("_drop$", names(x))]] 
}

microbenchmark::microbenchmark(f1(), f2(), f3(), f4())

#> Unit: microseconds
#>  expr      min        lq      mean   median       uq       max neval cld
#>  f1() 1574.201 1755.9010 2141.5060 1971.501 2303.651  6831.900   100  b 
#>  f2() 2861.602 3040.8505 3841.6990 3264.551 3920.701 17639.802   100   c
#>  f3()  471.801  527.6515  657.6511  588.501  702.851  2607.201   100 a  
#>  f4()  395.800  442.3005  583.3340  491.801  590.751  3824.800   100 a

关于r - 如何(有效地)在 R 中连接具有多个主键的表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64479380/

相关文章:

MySQL:不为第 1 列和第 2 列插入重复项

MYSQL嵌套内连接查询

r - dplyr 在改变数据帧时将日期变成双倍

python - R、statmodels、sklearn 与逻辑回归分类任务的比较

r - 使用 data.table 在每组数据前插入一行

r - 组合时间序列对象和列表:软件包“termstrc”

r - 在 R 中使用 str_split() 后获取第二项

r - 使用 write.table R 将行分开

mysql - SQL继承性能

r - 条形图 dplyr 汇总值