如何提速R中统计每个cdr3aa对应独特参与者数量的特定for循环?
R语言CDR3序列分组统计的循环提速优化方案
优化思路
你当前的需求本质是按cdr3aa序列分组,统计每组内唯一PartID的数量,属于典型的分组聚合场景,for循环存在大量重复数据筛选操作,性能极低,直接用向量化分组操作即可实现百倍级提速。
具体优化方案
方案1:基础R原生实现(无需额外安装包)
使用R内置的ave函数实现分组统计,底层为C语言实现,性能远高于纯R写的for循环:
# 直接删除原有第一行的as.numeric转换步骤,cdr3aa为字符串无需转数值 CDR3_post_challenge_unique_clonecount$participant_per_cdr3aa <- ave( CDR3_post_challenge_unique_clonecount$PartID, CDR3_post_challenge_unique_clonecount$cdr3aa, FUN = function(x) length(unique(x)) )
方案2:dplyr实现(代码可读性高,适合tidyverse用户)
用dplyr的分组 mutate 语法,逻辑清晰易维护:
library(dplyr) CDR3_post_challenge_unique_clonecount <- CDR3_post_challenge_unique_clonecount %>% group_by(cdr3aa) %>% mutate(participant_per_cdr3aa = n_distinct(PartID)) %>% ungroup()
方案3:data.table实现(性能最优,适合十万行以上大数据集)
免疫组库数据通常量级较大,data.table的原地修改+高性能分组实现是最优选择:
library(data.table) # 转换为data.table对象,无数据拷贝开销 setDT(CDR3_post_challenge_unique_clonecount) # 按cdr3aa分组直接新增列,原地修改内存占用极低 CDR3_post_challenge_unique_clonecount[, participant_per_cdr3aa := uniqueN(PartID), by = cdr3aa] # 若需要转回普通data.frame执行下行即可 # setDF(CDR3_post_challenge_unique_clonecount)
原有代码冗余说明
原代码第一行将cdr3aa转为numeric的操作完全无必要,字符串类型的cdr3aa转数值会生成大量NA,反而会导致统计结果错误,优化方案中均可直接删除该行逻辑。
内容的提问来源于stack exchange,提问作者Chinemerem
相关产品推荐
相关产品推荐

