【问题标题】:Join multiple tables dynamically动态连接多个表
【发布时间】:2019-11-14 14:40:22
【问题描述】:

问题

大家好,

我正在尝试动态地将几个数据框连接在一起。对我来说,这意味着我有一个以df_A 开头的数据框,我想加入多个其他数据框df_B1df_B2df_B3 等。

df_A 包含每个 df_B... 表要加入的列。 Column_join_B1Column_join_B2Column_join_B3 等(尽管实际上这些名称不详)。这些名称也在向量中df_A_join_names

df_B1df_B2df_B3 等都存储在列表df_B 中,我知道这是一个很好的做法:)。这也是我在循环中访问它们的方式。

每一个都有两列。一个具有加入 df_A 的价值,另一个具有信息。

我什至尝试重命名第一列以匹配加入前df_A 中的列,但无济于事。

我正在尝试什么

left_join() 不允许我简单地使用by = c(df_A_join_names[1], "Column_join_A"),所以我必须使用setNames,但我无法让它工作。

在我想循环迭代的函数下面:

my_join <- function(df_a, df_b, a_name, b_name){ 

  df_joined <- left_join(df_a, df_b, 
                            by = setNames(b_name, a_name))
  return(df_joined)
}

我想在循环中使用这个函数来加入我所有的df_B... 数据帧和df_A

for (i in 1: length(df_A_join_names)){

    df_A <- my_join(df_a = df_A,
                    df_b = df_B[i],
                    a_name = as.character(df_A_join_names[i]),
                    b_name = "Column_join_A"
    )
}

运行这个我得到:

 Error in UseMethod("tbl_vars") : 
  no applicable method for 'tbl_vars' applied to an object of class "list" 

一些可以玩的东西

#Making df_A
A_a <- seq(1,10, by = 1)
Column_join_B1 <- seq(11,20, by = 1)
Column_join_B2 <- seq(21,30, by = 1)
df_A <- data.frame(cbind(A_a, Column_join_B1, Column_join_B2) )

#Making df_B
Column_join_A <- seq(11,20, by = 1)
B_a <- LETTERS[1:10]
df_B1 <- data.frame(Column_join_A, B_a )

Column_join_A <- seq(21,30, by = 1)
B_b <- LETTERS[11:20]
df_B2 <- data.frame(Column_join_A, B_b)

# In my own code I make this using a loop. maybe not the prettiest.
df_B <- list()
df_B[[1]] <- df_B1
df_B[[2]] <- df_B2

df_A_join_names <- c("Column_join_B1", "Column_join_B2")

参考文献

我正在尝试应用这个:

Dplyr join on by=(a = b), where a and b are variables containing strings?

我很想听听你们的想法!

【问题讨论】:

  • 是否要将df_B 中的所有数据集加入df_A 以生成一个新数据?或者将df_B中的每个数据集分别加入df_A得到多个数据?
  • 我希望将 df_B 中的所有数据集加入到 df_A 以获得一个数据帧。

标签: r dataframe join


【解决方案1】:

不需要构建特定的函数,你可以简单地在 left_join 函数中使用 SetNames:

df_B_join_name <- "Column_join_A"

for (i in 1: length(df_A_join_names)){
  df_A <- left_join(df_A, df_B[[i]], by=c(setNames(nm = df_A_join_names[i], df_B_join_name)))
}   

【讨论】:

    【解决方案2】:

    你很亲密!您可能需要更改的唯一一件事是引用列表 df_B 下的数据框的方式。 df_B[1] 仍然是一个列表,df_B[[1]] 将返回一个数据框。我运行了下面的代码,它对我有用。

    for (i in 1: length(df_A_join_names)){
    
      df_A <- my_join(df_a = df_A,
                      df_b = df_B[[i]],
                      a_name = as.character(df_A_join_names[i]),
                      b_name = "Column_join_A"
      )
    }
    

    【讨论】:

      【解决方案3】:

      首先,设法重命名df_B 中的第一列以匹配df_A 中的列。所以df_B 看起来像这样:

      # [[1]]
      #    Column_join_B1 B_a
      # 1              11   A
      # 2              12   B
      # .              .    .
      # .              .    .
      # .              .    .
      # 
      # [[2]]
      #    Column_join_B2 B_b
      # 1              21   K
      # 2              22   L
      # .              .    .
      # .              .    .
      # .              .    .
      

      接下来,使用base 中的Reduce()purrr 中的reduce() 来迭代对left_join 的操作。你甚至不需要使用 for 循环。

      Reduce(left_join, df_B, init = df_A)
      
      #    A_a Column_join_B1 Column_join_B2 B_a B_b
      # 1    1             11             21   A   K
      # 2    2             12             22   B   L
      # 3    3             13             23   C   M
      # 4    4             14             24   D   N
      # 5    5             15             25   E   O
      # 6    6             16             26   F   P
      # 7    7             17             27   G   Q
      # 8    8             18             28   H   R
      # 9    9             19             29   I   S
      # 10  10             20             30   J   T
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-17
        • 1970-01-01
        相关资源
        最近更新 更多