R语言rcompanion包cldList无统计差异时终止运行的解决方案问询
问题原因
rcompanion包的cldList函数源代码中设置了所有组间比较都不显著时直接抛出错误终止运行,导致包含无显著差异分组的循环无法执行完全部目标。
你之前添加的
if (nrow(df2)==0) {df2 <- df1}逻辑不生效,是因为cldList遇到全不显著的分组时会直接抛出错误终止代码执行,后续的判断语句根本没有运行机会。
可行解决方案
提供两种可选方案,都可以实现循环完整运行、无差异分组标记相同字母的需求:
方案1:用tryCatch捕获错误,无需修改原函数
无需改动cldList本身,仅对原有循环逻辑做调整,运行时自动识别错误并生成符合要求的结果:
# 提前加载依赖包 library(rcompanion) library(multcompView) i <- 1 targets <- data.frame(Genes = unique(dummy_df$target)) df <- data.frame() while (i <= nrow(targets)) { print(i) current_target <- targets[i, ] sub_df <- subset(dummy_df, target == current_target) # 用tryCatch包裹cldList运行逻辑,捕获错误 df2 <- tryCatch({ # 正常有显著差异时返回原函数的计算结果 cldList(p.val~comparison, data = sub_df, threshold = 0.05) }, error = function(e) { # 触发全不显著错误时,自动提取所有分组标记相同字母 comps <- strsplit(sub_df$comparison, " - ") groups <- unique(unlist(comps)) data.frame(Group = groups, Letter = rep("a", length(groups)), MonoLetter = rep("a", length(groups))) }) df2$target <- current_target df <- rbind(df, df2) i <- i + 1 }
方案2:自定义修改版cldList,永久解决问题
直接修改原函数的错误抛出逻辑,后续可以直接调用自定义函数,不用每次都写错误捕获逻辑:
# 自定义修改版cldList custom_cldList = function(formula = NULL, data = NULL, comparison = NULL, p.value = NULL, threshold = 0.05, print.comp = FALSE, remove.space = TRUE, remove.equal = TRUE, remove.zero = TRUE, swap.colon = TRUE, swap.vs = FALSE, ...) { if(!is.null(formula)){ p.value = eval(parse(text=paste0("data","$",all.vars(formula[[2]])[1]))) comparison = eval(parse(text=paste0("data","$",all.vars(formula[[3]])[1]))) } Comparison = (as.numeric(p.value) <= threshold) # 替换原stop逻辑,全不显著时直接返回同字母结果 if (sum(Comparison) == 0){ if(remove.space == TRUE) {comparison = gsub(" ", "", comparison)} if(remove.equal == TRUE) {comparison = gsub("=", "", comparison)} if(remove.zero == TRUE) {comparison = gsub("0", "", comparison)} if(swap.colon == TRUE) {comparison = gsub(":", "-", comparison)} if(swap.vs == TRUE) {comparison = gsub("vs", "-", comparison)} groups <- unique(unlist(strsplit(comparison, "-"))) return(data.frame(Group = groups, Letter = rep("a", length(groups)), MonoLetter = rep("a", length(groups)))) } if(remove.space == TRUE) {comparison = gsub(" ", "", comparison)} if(remove.equal == TRUE) {comparison = gsub("=", "", comparison)} if(remove.zero == TRUE) {comparison = gsub("0", "", comparison)} if(swap.colon == TRUE) {comparison = gsub(":", "-", comparison)} if(swap.vs == TRUE) {comparison = gsub("vs", "-", comparison)} names(Comparison) = comparison if(print.comp == TRUE) {Y = data.frame(Comparisons = names(Comparison), p.value = p.value, Value=Comparison, Threshold=threshold) cat("\n", "\n") print(Y) cat("\n", "\n")} MCL = multcompLetters(Comparison, ...) Group = names(MCL$Letters) Letter = as.character(MCL$Letters) MonoLetter = as.character(MCL$monospacedLetters) Z = data.frame(Group, Letter, MonoLetter) return(Z) }
修改完自定义函数后,你原来的循环只要把cldList替换为custom_cldList就可以直接正常运行,无需修改其他逻辑。
结果说明
两种方案运行后,无显著差异的A4分组对应的e、c、d、f四个组别都会标记为相同的字母a,其他有显著差异的分组输出结果和原函数完全一致,循环可以完整跑完所有目标分组。
内容的提问来源于stack exchange,提问作者Sara Esteves
相关产品推荐
相关产品推荐

