You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R中合并行数相同、列不同的多个dataframe

在R中合并多个同行数、异列的DataFrame(共享键列)

问题说明

需要合并多个行数相同、列不同的DataFrame,它们共享x列作为键,期望得到行数与原DataFrame一致(如示例中的3行)、包含所有列的结果。但使用map_df读取并合并文件时,得到的是行堆叠且带大量NA的错误输出。

示例数据

df1 <- data.frame(
  x = c("A1", "A2", "A3"),
  y = c(1, 2, 3))
 
df2 <- data.frame(
  x = c("A1", "A2", "A3"),
  z = c(4, 5, 6))
 
df3 <- data.frame(
  x = c("A1", "A2", "A3"),
  a = c(7, 8, 9))

df4 <- data.frame(
  x = c("A1", "A2", "A3"),
  b = c(10, 11, 12))

错误代码及输出

错误代码:

files_list <- list.files("files", full.names = TRUE)
dfs <- files_list %>% 
    map_df(~read_csv(.x))

错误输出:

x y   z   a   b
1  A1 1  NA  NA  NA
2  A2 2  NA  NA  NA
3  A3 3  NA  NA  NA
4  A1 NA  4  NA  NA
5  A2 NA  5  NA  NA
6  A3 NA  6  NA  NA
7  A1 NA NA  7   NA
8  A2 NA NA  8   NA
9  A3 NA NA  9   NA
10 A1 NA NA  NA  10
11 A2 NA NA  NA  11
12 A3 NA NA  NA  12

解决方案

方法1:Tidyverse工具链(推荐)

map_df本质是按行堆叠数据,而我们需要的是基于共享键x的列合并。先将文件读取为DataFrame列表,再用reduce逐个合并:

library(dplyr)
library(purrr)

files_list <- list.files("files", full.names = TRUE)
# 读取为DataFrame列表,而非直接行绑定
dfs_list <- map(files_list, ~read_csv(.x))

# 按x列合并所有DataFrame
merged_df <- dfs_list %>% 
  reduce(inner_join, by = "x")

如果能确保所有DataFrame的行顺序完全与x列对应,也可以用bind_cols快速合并(需清理重复的x列):

merged_df <- dfs_list %>% 
  bind_cols() %>% 
  select(-matches("x\\.\\d+")) # 移除重复的x列

方法2:Base R实现

无需加载tidyverse包,用Reduce和merge函数即可完成:

files_list <- list.files("files", full.names = TRUE)
# 根据文件格式选择read.csv或read.table
dfs_list <- lapply(files_list, read.csv)

merged_df <- Reduce(function(x, y) merge(x, y, by = "x"), dfs_list)

错误原因

map_df是bind_rows的批量封装,它会将所有输入的DataFrame按行堆叠,因此4个3行的DataFrame会被拼接成12行,缺失的列自动填充NA,这与按键合并的需求逻辑不符。

内容的提问来源于stack exchange,提问作者Karina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:12:46