如何合并两个R DataFrame,保留非缺失值并合并同名列?
解决R数据框全连接后同名列合并问题
首先先定义你提供的两个数据框并完成全连接:
set.seed(1) df1 <- data.frame(id= 1:4, sex= c("m", "m", NA, NA), somevar= letters[1:4], whocares_var= rnorm(4)) df2 <- data.frame(id= 1:6, sex= c("m", NA, "m", NA, "m", NA), somevar= NA, morevars= LETTERS[1:6]) # 执行全连接,生成带.x/.y后缀的合并结果 merged_df <- merge(df1, df2, by = "id", all = TRUE, suffixes = c(".x", ".y"))
下面提供两种实现同名列合并的方法,均满足保留非缺失值、无冲突时取有效数据、保留独列的需求:
方法一:Base R原生实现
无需额外安装包,直接用基础函数处理:
- 提取所有重复列的原始名称(即去掉
.x后缀的列名)
dup_cols <- unique(sub("\\.x$", "", grep("\\.x$", colnames(merged_df), value = TRUE)))
- 循环合并每组重复列,移除原后缀列
for (col in dup_cols) { # 优先取.x列的值,若为NA则取.y列的值 merged_df[[col]] <- ifelse(is.na(merged_df[[paste0(col, ".x")]]), merged_df[[paste0(col, ".y")]], merged_df[[paste0(col, ".x")]]) # 删除原有的.x和.y列 merged_df <- merged_df[, !colnames(merged_df) %in% c(paste0(col, ".x"), paste0(col, ".y"))] }
方法二:Tidyverse(dplyr)实现
代码更简洁,适合熟悉tidyverse生态的用户:
library(dplyr) merged_df <- df1 %>% full_join(df2, by = "id", suffix = c(".x", ".y")) %>% # 批量合并所有带.x后缀的列与对应.y列,保留非缺失值 mutate(across(ends_with(".x"), ~coalesce(., get(sub("\\.x$", ".y", cur_column()))), .names = "{sub('\\.x$', '', .col)}")) %>% # 移除所有带.x/.y后缀的原始列 select(-ends_with(c(".x", ".y")))
执行完任意一种方法后,查看最终结果:
print(merged_df)
内容的提问来源于stack exchange,提问作者LulY
相关产品推荐
相关产品推荐

