如何用tidyverse或其他方法合并DataFrame同核心名多列为单列?
合并R语言DataFrame分组列的实现方法
原始数据
你提供的原始DataFrame代码如下:
nr=c(1:6) s_psy01=c(NA,NA,NA,NA,4,5) l_psy01=c(NA,NA,2,3,NA,NA) r_psy01=c(2,5,NA,NA,NA,NA) s_psy02=c(NA,NA,NA,NA,2,3) l_psy02=c(NA,NA,5,2,NA,NA) r_psy02=c(3,5,NA,NA,NA,NA) s_psy03=c(NA,NA,NA,NA,2,4) l_psy03=c(NA,NA,2,5,NA,NA) r_psy03=c(1,3,NA,NA,NA,NA) df <- data.frame(nr,s_psy01, l_psy01, r_psy01, s_psy02, l_psy02, r_psy02, s_psy03, l_psy03, r_psy03)
需求说明
需要将每组s_psyXX、l_psyXX、r_psyXX三列合并为单个psyXX列,由于每组三列的NA值互补(每行仅含一个非NA值),核心操作是提取每行的非NA值。
方法一:使用tidyverse工具包
借助dplyr的mutate()配合tidyr的coalesce()函数,高效完成合并:
library(tidyverse) # 生成合并列并筛选目标列 df_processed <- df %>% mutate( # 按顺序取每行第一个非NA值 psy01 = coalesce(s_psy01, l_psy01, r_psy01), psy02 = coalesce(s_psy02, l_psy02, r_psy02), psy03 = coalesce(s_psy03, l_psy03, r_psy03) ) %>% select(nr, starts_with("psy")) # 可选:仅保留nr和新生成的psy列
说明:coalesce()函数会依次检查每行的列,返回第一个非NA值,完美适配你的数据结构。如果不需要保留原始列,select()可以快速筛选出目标列。
方法二:基础R实现
无需额外加载包,用apply()逐行处理分组列:
# 初始化结果表 df_processed_base <- df # 逐组合并列 df_processed_base$psy01 <- apply(df_processed_base[, c("s_psy01", "l_psy01", "r_psy01")], 1, function(x) x[!is.na(x)]) df_processed_base$psy02 <- apply(df_processed_base[, c("s_psy02", "l_psy02", "r_psy02")], 1, function(x) x[!is.na(x)]) df_processed_base$psy03 <- apply(df_processed_base[, c("s_psy03", "l_psy03", "r_psy03")], 1, function(x) x[!is.na(x)]) # 可选:删除原始的s/l/r开头列,仅保留目标列 df_processed_base <- df_processed_base[, c("nr", "psy01", "psy02", "psy03")]
说明:apply()按行遍历每组列,提取其中的非NA值(因每行仅一个非NA值,直接返回该值即可)。
内容的提问来源于stack exchange,提问作者user10904839
相关产品推荐
相关产品推荐

