R语言:分组数据框中tx_ID统计与带缺失值的横向展开实现
R处理移植随访数据:统计患者移植ID数量并拆分至独立列
背景
现有一份记录患者移植后随访数据的dataframe,包含3个关键变量:
patient_ID(患者标识)tx_ID(移植手术唯一标识)days_from_tx(移植至随访的间隔天数)
每一行代表一次随访,每位患者的随访次数不固定;部分随访记录的tx_ID存在缺失,部分患者有多次移植手术,tx_ID不同,且无法确定单患者最大tx_ID数量。
需求
- 统计每位患者拥有的唯一
tx_ID数量(0、1、2……,不计入缺失值); - 将每位患者的所有唯一
tx_ID提取至独立列(如tx1、tx2),对应到该患者的所有随访记录。
示例数据
patient_ID <- c("A", "A", "A", "A", "B", "B", "C", "C", "C") tx_ID <- c("123", NA, NA, "123", NA, NA, "456", NA, "789") days_from_tx <- c(0, 5, 10, 15, 2, 4, 1, 2, 3) df <- data.frame(patient_ID, tx_ID, days_from_tx)
数据展示:
| patient_ID | tx_ID | days_from_tx |
|---|---|---|
| A | 123 | 0 |
| A | 5 | |
| A | 10 | |
| A | 123 | 15 |
| B | 2 | |
| B | 4 | |
| C | 456 | 3 |
| C | 10 | |
| C | 789 | 2 |
期望输出
patient_ID tx_ID days_from_tx nr_tx_ID tx1 tx2 1 A 123 0 1 123 <NA> 2 A <NA> 5 1 123 <NA> 3 A <NA> 10 1 123 <NA> 4 A 123 15 1 123 <NA> 5 B <NA> 2 0 <NA> <NA> 6 B <NA> 4 0 <NA> <NA> 7 C 456 3 2 456 789 8 C <NA> 10 2 456 789 9 C 789 2 2 456 789
尝试的代码及问题
参考相关方案修改的代码:
df %>% group_by(patient_ID) %>% mutate( last_followup = n_distinct(tx_ID, na.rm = TRUE) )
问题:代码未按患者分组统计,反而将所有患者的唯一tx_ID数量统一写入列中,不符合需求。
解决方案
可以通过dplyr结合tidyr实现需求,步骤如下:
- 按
patient_ID分组,提取每组的唯一tx_ID(去重并排除NA); - 统计每组的
tx_ID数量,生成nr_tx_ID列; - 将提取的唯一
tx_ID转换为宽格式,合并回原数据框。
完整代码:
library(dplyr) library(tidyr) df_result <- df %>% group_by(patient_ID) %>% # 提取每组唯一的tx_ID,排除NA,生成列表列 mutate(unique_tx = list(unique(na.omit(tx_ID)))) %>% # 统计tx_ID数量 mutate(nr_tx_ID = length(unique_tx[[1]])) %>% # 将列表列展开为多列,自动命名tx1、tx2... unnest_wider(unique_tx, names_sep = "") %>% # 未填满的列补NA mutate(across(starts_with("unique_tx"), ~replace_na(.x, NA))) %>% # 重命名列,去掉前缀unique_ rename_with(~gsub("unique_tx", "tx", .x), starts_with("unique_tx")) %>% ungroup() print(df_result)
运行后即可得到符合期望的输出。
内容的提问来源于stack exchange,提问作者kobue1
相关产品推荐
相关产品推荐

