R语言合并DataFrame列:保留非NA值,纯NA行保留NA
解决每行仅一个非NA值的DataFrame列合并问题
嘿,我明白你的需求啦——把每行只有一个非NA值的多列合并成单独一列,同时全NA的行还要保留NA,对吧?我给你几个在R里实用的解决方案:
首先先补全你的示例数据(新增了全NA的行,更贴合你的场景):
# 补全后的示例数据 data <- data.frame( 'a' = c('A','B','C','D','E','F','G'), 'x' = c(1,2,NA,NA,NA,NA,NA), 'y' = c(NA,NA,3,NA,NA,NA,NA), 'z' = c(NA,NA,NA,4,NA,NA,NA), 'w' = c(NA,NA,NA,NA,5,6,NA) )
方法一:Tidyverse工具链(推荐)
用dplyr的rowwise()+c_across()配合tidyr的coalesce(),简洁高效,自动处理全NA行:
library(dplyr) library(tidyr) data_combined <- data %>% rowwise() %>% # 合并x到w列,取每行第一个非NA值,全NA则返回NA mutate(combined = coalesce(c_across(x:w))) %>% ungroup()
方法二:Base R原生方法(无需额外包)
如果不想加载包,可以用apply()逐行处理,自定义函数解决:
# 定义函数:提取每行的非NA值,无则返回NA get_single_non_na <- function(row) { non_na_vals <- row[!is.na(row)] if (length(non_na_vals) == 0) NA else non_na_vals[1] } # 应用到目标列,生成新列 data$combined <- apply(data[, c('x','y','z','w')], 1, get_single_non_na)
方法三:宽转长再提取(适合排查数据)
如果需要清晰看到非NA值的来源列,可以先转长表再筛选:
library(tidyr) library(dplyr) data_combined <- data %>% pivot_longer(cols = x:w, names_to = "source_col", values_to = "combined", values_drop_na = FALSE) %>% # 保留非NA行,或全NA行仅保留一条 filter(!is.na(combined) | (is.na(combined) & !duplicated(a))) %>% select(-source_col) %>% distinct(a, .keep_all = TRUE)
这三种方法都能完美实现你的需求:合并后列保留每行的非NA值,全NA行则保留NA。
内容的提问来源于stack exchange,提问作者arielle
相关产品推荐
相关产品推荐

