如何用dplyr合并行数不等且共享首列的多个data.frame?
批量合并共享键的多data.frame(缺失值补NA)
核心思路
当多个data.frame共享同一键列(第一列)但行数不同时,bind_cols会因行不匹配报错,bind_rows是纵向堆叠而非按键合并,此时可以用purrr::reduce结合dplyr::full_join实现批量按键合并,自动为缺失值补NA。
示例实现
1. 构造测试数据
先模拟场景中的多个两列data.frame并存入列表:
library(dplyr) library(purrr) # 构造单个data.frame df1 <- tibble(id = c(1,2,3), value_a = c("a","b","c")) df2 <- tibble(id = c(2,3,4), value_b = c("x","y","z")) df3 <- tibble(id = c(1,3,5), value_c = c("m","n","p")) # 存入列表 df_list <- list(df1, df2, df3)
2. 批量合并操作
直接用reduce对列表中的data.frame依次执行全连接:
# 按id列批量全连接 merged_df <- df_list %>% reduce(full_join, by = "id") # 查看结果 merged_df
输出结果会保留所有id值,缺失的对应列自动补NA:
# A tibble: 5 × 4 id value_a value_b value_c <dbl> <chr> <chr> <chr> 1 1 a NA m 2 2 b x NA 3 3 c y n 4 4 NA z NA 5 5 NA NA p
3. 处理列名重复的情况
如果所有data.frame第二列名字相同(比如都叫value),合并后会自动生成value.x、value.y这类后缀,可先批量重命名列再合并:
# 重命名列表中每个data.frame的第二列,添加序号后缀 df_list_renamed <- df_list %>% imap(~ rename(.x, !!paste0("value_", .y) := 2)) # 再执行合并 merged_df_renamed <- df_list_renamed %>% reduce(full_join, by = "id")
关键说明
reduce函数会遍历列表,将前一次合并的结果与下一个data.frame继续执行full_join,实现批量合并,无需手动逐个处理数百个data.frame。full_join会保留所有键值(即第一列的所有唯一值),不存在的匹配项自动填充NA,完全匹配需求。
内容的提问来源于stack exchange,提问作者C. Sebastian
相关产品推荐
相关产品推荐

