如何合并多列数据框中同一ID的多行数据,整合个体各器官测量值
实现方案
你的需求核心是按个体ID分组聚合,把每组内各器官列的非NA有效值合并为单行,你之前用melt是做宽表转长表的操作,和需求方向相反,所以无法得到预期结果,以下是两种可直接运行的实现方法:
方法1:基础R实现(无需额外安装依赖包)
用aggregate函数直接按ID分组,对每列提取非NA的有效值即可:
# 读入你的原始数据 df <- structure(list(ID = c("BB1", "BB1", "BB1"), ID.organ = c("BB1-B", "BB1-L", "BB1-M"), d15NAIR = c(6.244803447, 5.263374719, 6.28820367 ), brain = c(-31.00047084, NA, NA), eyes = c(NA_real_, NA_real_, NA_real_), liver = c(NA, -30.8483728, NA), muscle = c(NA, NA, -29.67755736)), row.names = c(NA, 3L), class = "data.frame") # 按ID分组聚合,每列取第一个非NA值 result <- aggregate(. ~ ID, data = df, FUN = function(x) na.omit(x)[1], na.action = na.pass)
运行后得到的result就是每个ID对应一行、各器官数值为独立列的结果,你示例中的BB1行对应器官列会自动填充对应非NA值,无数据的eyes列保留NA。
方法2:tidyverse套件实现(灵活性更高,方便后续扩展处理)
如果你的数据后续还要做其他清洗分析,可以用dplyr的分组聚合逻辑实现:
library(dplyr) result <- df %>% group_by(ID) %>% summarise( # 对所有器官数值列提取非NA值 brain = na.omit(brain)[1], liver = na.omit(liver)[1], muscle = na.omit(muscle)[1], eyes = na.omit(eyes)[1], # 如果需要保留各器官对应的d15NAIR值,可以新增对应列,示例如下 d15N_brain = na.omit(ifelse(!is.na(brain), d15NAIR, NA))[1], d15N_liver = na.omit(ifelse(!is.na(liver), d15NAIR, NA))[1], d15N_muscle = na.omit(ifelse(!is.na(muscle), d15NAIR, NA))[1] )
如果不需要保留分器官的d15NAIR值,删除对应的新增列代码即可。
内容的提问来源于stack exchange,提问作者Nadiine El Nino
相关产品推荐
相关产品推荐

