R语言:微生物分类器多方法结果的最优分类谱系提取需求
R语言实现微生物分类结果的最优选择方案
问题背景
在微生物谱系分类器研究中,需要从三种分类方法的结果里按规则筛选出最优分类记录。现有R数据框df,每条记录以;分隔科、属、种三个分类阶元,示例数据如下:
df <- data.frame( classifier_a = c("Lachnospiraceae;Blautia;NA", 'Succinivibrionaceae;Succinivibrio;NA', 'NA;NA;NA'), classifier_b = c('Lachnospiraceae;Blautia;Blautia faecis', 'Succinivibrionaceae;Succinivibrio;NA', 'UGC-10;NA;NA'), classifier_c= c('Lachnospiraceae;Blautia;Blautia faecis', 'Succinivibrionaceae;Succinivibrio;Succinivibrio dextrinosolvens', 'NA;NA;NA') )
原方法的不足
最初尝试用统计众数提取每行最常见结果,但无法满足实际需求:
- 第二行中,
classifier_c提供了完整的科、属、种信息,但众数结果仅到属级别(缺失种信息); - 第三行中,所有结果里只有
classifier_b有有效科信息,此时需选择NA最少的结果,而非无意义的众数。
需求规则
- 优先选择统计众数对应的分类结果;
- 若众数的分类阶元存在NA(信息不完整),则选择该行中NA数量最少的分类结果;
- 若存在多个NA数量相同的结果,优先选择与众数分类阶元匹配度最高的(或按列顺序取第一个符合条件的)。
期望输出
最终期望得到包含最优结果的数据集:
df <- data.frame( classifier_a = c("Lachnospiraceae;Blautia;NA", 'Succinivibrionaceae;Succinivibrio;NA', 'NA;NA;NA'), classifier_b = c('Lachnospiraceae;Blautia;Blautia faecis', 'Succinivibrionaceae;Succinivibrio;NA', 'UGC-10;NA;NA'), classifier_c= c('Lachnospiraceae;Blautia;Blautia faecis', 'Succinivibrionaceae;Succinivibrio;Succinivibrio dextrinosolvens', 'NA;NA;NA'), desired_output=c("Lachnospiraceae;Blautia;Blautia faecis", "Succinivibrionaceae;Succinivibrio;Succinivibrio dextrinosolvens","UGC-10;NA;NA") )
解决方案代码
# 自定义众数函数:返回出现次数最多的元素,若多个则返回第一个 get_mode <- function(x) { tab <- table(x) max_count <- max(tab) names(tab[tab == max_count])[1] } # 逐行处理数据 df$desired_output <- apply(df, 1, function(row) { # 1. 拆分每个分类结果为三个阶元,统计NA数量 split_vals <- strsplit(row, ";") na_counts <- sapply(split_vals, function(x) sum(x == "NA")) # 2. 获取当前行的众数结果 mode_val <- get_mode(row) # 3. 检查众数的NA数量是否为当前行最少 mode_na_count <- na_counts[which(row == mode_val)[1]] min_na_count <- min(na_counts) if (mode_na_count == min_na_count) { # 众数信息最完整,直接返回 mode_val } else { # 筛选NA数量最少的结果,优先选择与众数阶元匹配最多的 candidates <- row[na_counts == min_na_count] match_scores <- sapply(strsplit(candidates, ";"), function(x) { mode_split <- strsplit(mode_val, ";")[[1]] sum(x == mode_split & x != "NA") }) candidates[which.max(match_scores)] } }) # 查看结果 df
代码解释
- 自定义众数函数:处理多众数场景,返回第一个出现次数最多的元素;
- 逐行逻辑:
- 拆分每个分类结果为科、属、种字段,统计每个结果的NA数量;
- 获取当前行众数,检查其NA数量是否为最小值;
- 若众数信息不完整,筛选NA最少的候选结果,再从中挑选与众数分类阶元匹配度最高的项;
- 最终将最优结果写入
desired_output列。
内容的提问来源于stack exchange,提问作者MagíBC
相关产品推荐
相关产品推荐

