R语言如何按基因、时间点分组统计对应唯一参与者ID数量?
原代码错误原因
- 内层循环中反复对原始数据集
IgH_CDR3_post_challenge_unique执行filter并覆盖赋值,每一轮循环后原始数据都会被裁剪为仅含当前时间点的子集,后续循环无法用到全量数据 - 遍历
time_list时直接将时间点值(如C0、C1)作为索引调用time_list[i],无法正确匹配到目标时间点 - 统计参与者数量时没有按时间点分组,得到的结果是全局基因对应的参与者数,不是分时间点的统计值
正确实现方案
方案1:修正后的嵌套循环实现
# 先保留原始全量数据,避免覆盖修改 raw_data <- select(IgH_CDR3_post_challenge_unique, cdr3aa, gene, ID, Timepoint) # 新建空结果列 raw_data$participant_per_gene <- NA participant_list <- unique(raw_data$gene) time_list <- unique(raw_data$Timepoint) for (c in participant_list) { for (i in time_list) { # 仅筛选当前基因+当前时间点的子集,不修改原数据 current_sub <- filter(raw_data, gene == c, Timepoint == i) # 计算唯一参与者数量 count <- length(unique(current_sub$ID)) # 将统计值回填到原数据对应位置 raw_data$participant_per_gene[raw_data$gene == c & raw_data$Timepoint == i] <- count } }
如果需要提取独立的汇总统计表,额外执行stat_result <- distinct(raw_data, gene, Timepoint, participant_per_gene)即可。
方案2:更简洁的tidyverse分组统计(推荐)
无需手动写循环,用分组统计逻辑更清晰、出错概率更低:
library(dplyr) # 按时间点、基因分组,直接统计唯一参与者数量 stat_result <- IgH_CDR3_post_challenge_unique %>% group_by(Timepoint, gene) %>% summarise(participant_per_gene = n_distinct(ID), .groups = "drop") # 如果需要把统计结果回写到原始数据集,补充左连逻辑即可 IgH_CDR3_post_challenge_unique <- IgH_CDR3_post_challenge_unique %>% left_join(stat_result, by = c("Timepoint", "gene"))
按你提供的示例数据,最终统计结果如下:
| gene | Timepoint | participant_per_gene |
|---|---|---|
| 1 | C0 | 2 |
| 2 | C1 | 1 |
| 3 | C0 | 1 |
内容的提问来源于stack exchange,提问作者Chinemerem
相关产品推荐
相关产品推荐

