【问题标题】:How to join multiple data frames using dplyr?如何使用 dplyr 连接多个数据框?
【发布时间】:2016-03-24 11:44:59
【问题描述】:

我要left_join多个数据框:

dfs <- list(
  df1 = data.frame(a = 1:3, b = c("a", "b", "c")),
  df2 = data.frame(c = 4:6, b = c("a", "c", "d")),
  df3 = data.frame(d = 7:9, b = c("b", "c", "e"))
)
Reduce(left_join, dfs)
#   a b  c  d
# 1 1 a  4 NA
# 2 2 b NA  7
# 3 3 c  5  8

之所以有效,是因为它们都有相同的b 列,但Reduce 不允许我指定可以传递给left_join 的其他参数。有这样的解决方法吗?

dfs <- list(
  df1 = data.frame(a = 1:3, b = c("a", "b", "c")),
  df2 = data.frame(c = 4:6, d = c("a", "c", "d")),
  df3 = data.frame(d = 7:9, b = c("b", "c", "e"))
)

更新

这种工作:Reduce(function(...) left_join(..., by = c("b" = "d")), dfs) 但是当by 是多个元素时,它会给出这个错误:Error: cannot join on columns 'b' x 'd': index out of bounds

【问题讨论】:

  • 你不能Reduce(function(...) left_join(..., other args here), dfs)吗?
  • 我没想到。我可以!随意写它作为你的答案
  • 嗯,实际上,如果by 有多个元素,这会中断。查看更新
  • 您希望函数如何知道要加入哪些列?这并不是 *_join 函数设计的真正目的。如果所有列都有一个可以使用的公共 ID 列,那么您的更新可以解决问题。否则,您将不得不手动指定用于每对连接的列。
  • 试试 purrr:reduce() 代替吗?

标签: r dplyr reduce


【解决方案1】:

我知道已经太晚了....今天我被介绍到未回答的问题部分。抱歉打扰了。

使用left_join()

dfs <- list(
              df1 = data.frame(b = c("a", "b", "c"), a = 1:3),
              df2 = data.frame(d = c("a", "c", "d"), c = 4:6),
              df3 = data.frame(b = c("b", "c", "e"), d = 7:9)
         )

func <- function(...){
  df1 = list(...)[[1]]
  df2 = list(...)[[2]]
  col1 = colnames(df1)[1]
  col2 = colnames(df2)[1]
  xxx = left_join(..., by = setNames(col2,col1))
  return(xxx)
}
Reduce( func, dfs)
#  b a  c  d
#1 a 1  4 NA
#2 b 2 NA  7
#3 c 3  5  8

使用merge()

func <- function(...){
  df1 = list(...)[[1]]
  df2 = list(...)[[2]]
  col1 = colnames(df1)[1]
  col2 = colnames(df2)[1]
  xxx=merge(..., by.x = col1, by.y = col2, , all.x = T)
  return(xxx)
}

Reduce( func, dfs)
#  b a  c  d
#1 a 1  4 NA
#2 b 2 NA  7
#3 c 3  5  8

【讨论】:

  • 请注意:我必须将“关键”变量保留为第一列,因为合并后它们会自动成为数据框中的第一列
【解决方案2】:

这对你有用吗?

jnd.tbl <- df1 %>%
    left_join(df2, by='b') %>%
    left_join(df3, by='d')

【讨论】:

  • 不能很好地概括(这似乎是问题的重点)。
  • 这似乎是最好的解决方案。事实上,它概括得很好:如果你想加入另一个表,只需在管道中再添加一行。该代码最终看起来与 SQL 多连接查询没有太大区别。
  • @HongOoi 但 by= 变量不一样吗?请检查我对此的回答
猜你喜欢
  • 2021-06-09
  • 2018-09-25
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多