在R中按组pivot_wider并导出CSV:移除空列与单值行
批量处理生物标志物数据并导出合规CSV
针对现有数据框dat0,我们需要将其转换为宽格式后,按biomarker分组导出CSV,同时完成以下批量处理要求:
- 移除仅含单个结果的行(仅保留有多个分析仪结果的配对行)
- 删除转换后产生的空列
- 将NA单元格显示为空
以下是适配10000+行、150+生物标志物的批量处理代码:
library(tidyverse) # 1. 转换为宽格式,保留id和biomarker列 dat1 <- dat0 %>% pivot_wider(names_from = analyser, values_from = result) # 2. 按biomarker分组处理并导出 dat1 %>% group_by(biomarker) %>% group_walk(function(.x, .y) { # 移除仅含单个结果的行:计算每行非NA值数量,保留≥2的行 filtered_rows <- .x %>% rowwise() %>% mutate(n_non_na = sum(!is.na(c_across(starts_with(c("A", "B", "C")))))) %>% ungroup() %>% filter(n_non_na >= 2) %>% select(-n_non_na) # 删除空列:移除全为NA的列 filtered_cols <- filtered_rows %>% select(where(~!all(is.na(.x)))) # 导出CSV,将NA转为空字符串 write_csv(filtered_cols, file = paste0(.y$biomarker, ".csv"), na = "") })
代码说明
- 宽格式转换:使用
pivot_wider将analyser作为列名,result作为对应值,保留id和biomarker作为标识列。 - 行过滤:通过
rowwise()和c_across()统计每行非NA结果的数量,仅保留数量≥2的行(即有配对结果的行)。 - 列过滤:使用
select(where(~!all(is.na(.x))))移除全为NA的空列。 - 导出设置:
write_csv的na = ""参数将NA转为空字符串,满足显示要求。
初始数据示例
原数据框dat0结构如下:
dat0 <- structure(list(id = c("0240307415", "0240307373", "0240326970", "0240326976", "0240322181", "0240322185", "0240322191", "0240326976", "0240326970", "0240326981", "0240326975", "0240307415", "0240307415", "0240307373", "0240322181", "0240322185", "0240322191", "0240326976", "0240326970", "0240326981", "0240326975", "0240307415", "0240252218", "0240307417", "0240307415", "0240307373", "0240322181", "0240322185", "0240322191", "0240322151"), biomarker = c("BICAR", "BICAR", "AMMO", "AMMO", "HAPTO", "HAPTO", "HAPTO", "AMMO", "AMMO", "AMMO", "AMMO", "BICAR", "BICAR", "BICAR", "HAPTO", "HAPTO", "HAPTO", "AMMO", "AMMO", "AMMO", "AMMO", "BICAR", "BICAR", "BICAR", "BICAR", "BICAR", "HAPTO", "HAPTO", "HAPTO", "HAPTO"), analyser = c("A1", "A1", "A2", "A2", "A3", "A3", "A3", "B1", "B1", "B1", "B1", "B1", "B2", "B2", "B2", "B2", "B2", "C1", "C1", "C1", "C1", "C1", "C1", "C1", "C2", "C2", "C2", "C2", "C2", "C2"), result = c(27, 23, 657, 603, 6, 4, 4, 744, 623, 550, 490, 28, 27, 23, 5, 5, 4, 772, 649, 570, 509, 29, 25, 23, 28, 23, 5, 5, 4, 4)), row.names = c(NA, -30L), class = "data.frame")
内容的提问来源于stack exchange,提问作者denis
相关产品推荐
相关产品推荐

