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

在R语言中按Study_ID填充患者特征缺失值的技术求助

解决方案:按患者ID填充NA值

你可以通过按Study_ID分组,将每个患者的非NA特征值复制到同ID的所有记录中,以下是两种常用实现方法:

先加载示例数据

首先把你提供的数据加载到R中:

patient.info <- structure(list(Study_ID = c(104, 104, 108, 108, 114, 114), Group = c("BS", 
NA, "BS", NA, "BS", NA), Group2 = c("MO", NA, "MO", NA, "MO", 
NA), Age = c(50.5, NA, 33.5, NA, 51.7, NA), Sex = c("F", NA, 
"F", NA, "F", NA), Sex2 = c(2L, NA, 2L, NA, 2L, NA), Ethnicity = c("A", 
NA, "D", NA, "C", NA), Eth2 = c("EW", NA, "AF M", NA, "EW", NA
)), row.names = c(35L, 36L, 40L, 41L, 49L, 50L), class = "data.frame")

方法1:使用tidyverse(dplyr)

这是生物信息学中常用的tidy风格方法,代码简洁易读:

library(dplyr)

# 按Study_ID分组,双向填充所有列的NA值
filled_data <- patient.info %>%
  group_by(Study_ID) %>%
  fill(everything(), .direction = "downup") %>%
  ungroup()
  • group_by(Study_ID):将数据按患者ID分组
  • fill(everything(), .direction = "downup"):对所有列进行双向填充(不管NA在非NA值的上方还是下方,都会被替换为该分组的非NA值)
  • ungroup():取消分组,恢复普通数据框结构

你也可以用更明确的取值方式,效果完全一致:

filled_data <- patient.info %>%
  group_by(Study_ID) %>%
  mutate(across(everything(), ~ ifelse(is.na(.), first(na.omit(.)), .))) %>%
  ungroup()

方法2:使用data.table

如果你的数据集很大(生物信息学常遇到这种情况),data.table的速度会更快:

library(data.table)

# 将数据框转为data.table格式
setDT(patient.info)

# 按Study_ID分组,替换NA为对应列的非NA值
filled_data <- patient.info[, lapply(.SD, function(x) {
  # 取当前列的第一个非NA值,替换所有NA
  x[is.na(x)] <- x[!is.na(x)][1]
  x
}), by = Study_ID]

验证结果

运行后查看填充后的数据:

head(filled_data)

可以看到每个Study_ID的所有记录都已经填充了对应的特征值,NA被完全替换。

注意:如果某个患者的某列全为NA,填充后仍会保留NA(因为没有可用的特征值)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 17:42:40