如何高效筛选仅单个样本中存在的专属ASV?(R语言dplyr)
提取专属ASV的高效实现方案
需求明确:要提取专属ASV——也就是某ASV仅在指定样本(比如MM2)中数值大于0,其余所有样本数值全为0。样本数量多的时候,手动写一堆filter条件太麻烦,这里给几个简洁高效的实现方法:
单个样本的快速过滤
不用逐个列写判断条件,直接判断「目标样本值>0,且其他所有样本值都≤0」:
library(dplyr) # 提取仅在MM2中存在的ASV asv_mm2 <- asv_table %>% rowwise() %>% filter(MM2 > 0 & sum(c_across(-MM2) > 0) == 0) %>% ungroup()
代码解释
rowwise():让数据按行处理,确保每一行单独计算c_across(-MM2):选中除MM2外的所有样本列sum(...) > 0:统计其他样本里有多少个值大于0,等于0就说明其他全是0- 最后
ungroup()取消按行分组,避免后续操作出问题
批量处理所有样本
如果要一次性生成每个样本的专属ASV列表,用purrr包批量处理更省心:
library(dplyr) library(purrr) # 获取所有样本的列名 sample_cols <- colnames(asv_table) # 批量生成每个样本的专属ASV sample_specific_asvs <- map(sample_cols, function(sample_col) { asv_table %>% rowwise() %>% filter(!!sym(sample_col) > 0 & sum(c_across(-!!sym(sample_col)) > 0) == 0) %>% ungroup() }) # 给列表命名,方便按样本名调用 names(sample_specific_asvs) <- sample_cols # 比如调用MM2的专属ASV sample_specific_asvs[["MM2"]]
Base R 替代方案
如果不想加载额外包,用Base R也能实现:
# 单个样本MM2 target_col <- "MM2" other_cols <- setdiff(colnames(asv_table), target_col) asv_mm2 <- asv_table[asv_table[[target_col]] > 0 & rowSums(asv_table[other_cols] > 0) == 0, ] # 批量处理所有样本 sample_specific_asvs <- lapply(colnames(asv_table), function(target_col) { other_cols <- setdiff(colnames(asv_table), target_col) asv_table[asv_table[[target_col]] > 0 & rowSums(asv_table[other_cols] > 0) == 0, ] }) names(sample_specific_asvs) <- colnames(asv_table)
这些方法不管样本数量有多少,都不用手动写一堆判断条件,既高效又不容易出错。
内容的提问来源于stack exchange,提问作者Soluna salles
相关产品推荐
相关产品推荐

