循环中ggpubr::stat_pvalue_manual(hide.ns=T)报错‘label未找到’排查
问题:循环批量生成带显著性标记的图表时,
hide.ns=T 参数报错 我需要按不同测量指标、性别批量生成图表,因为无法使用 facet.wrap,所以采用循环实现。
步骤1:生成统计显著性数据框
emmeans_c<- data_all_c %>% group_by(sex, light_c, measurement) %>% emmeans_test(values~group, p.adjust.method = "bonferroni")%>% add_xy_position( x = "light_c", dodge = 0.9)
步骤2:循环生成图表的代码
使用 ggpubr::stat_pvalue_manual 映射显著性结果,设置 hide.ns=T 隐藏无显著差异的结果:
for(m in unique(data_all_c$measurement)){ for (s in unique(data_all_c$sex)) { const <- ggplot(subset(data_all_c, sex == s | measurement == m))+ aes(x = light_c, y = values, fill = group)+ stat_summary(fun.data = mean_se, geom = "bar", position = "dodge")+ stat_summary(fun.data = mean_se, geom = "errorbar", position = position_dodge(width = 0.9),width = 0.2, show.legend = FALSE)+ stat_pvalue_manual(subset(emmeans_c, sex == s & measurement == m), label = "p.adj.signif", xmin = "xmin", xmax = "xmax", step.group.by = "group1", color = "darkgrey" ,inherit.aes = FALSE, hide.ns = T ) print(const) }}
报错情况
手动子集数据时代码正常运行,但放入循环后报错:
Error: ! Problem while computing aesthetics. ℹ Error occurred in the 3rd layer. Caused by error in `FUN()`: ! object 'label' not found
设置 hide.ns=F 时循环可正常运行。请问是该参数不支持循环使用,还是我的代码存在未发现的错误?
模拟数据
data_all_c<-rbind(as.data.frame(cbind(rbind(cbind(light_c = c("day", "night", "24h"),sex = "f", group = "A"), cbind(light_c = c("day", "night", "24h"),sex = "m", group = "A")), rbind( as.data.frame(cbind( measurement = "Flow" ,values = rnorm(50, mean = 5, sd = 0.008))), as.data.frame(cbind(measurement = "Temp",values = rnorm(50, mean = 23, sd = 1))), as.data.frame(cbind(measurement = "Hum", values = rnorm(50, mean = 25, sd = 5))) ))), as.data.frame(cbind(rbind(cbind(light_c = c("day", "night", "24h"),sex = "f", group = "B"), cbind(light_c = c("day", "night", "24h"),sex = "m", group = "B")), rbind( as.data.frame(cbind( measurement = "Flow" ,values = rnorm(50, mean = 0.5, sd = 0.01))), as.data.frame(cbind(measurement = "Temp",values = rnorm(50, mean = 22, sd = 0.8))), as.data.frame(cbind(measurement = "Hum", values = rnorm(50, mean = 50, sd = 2))) ))), as.data.frame(cbind(rbind(cbind(light_c = c("day", "night", "24h"),sex = "f", group = "C"), cbind(light_c = c("day", "night", "24h"),sex = "m", group = "C")), rbind( as.data.frame(cbind( measurement = "Flow" ,values = rnorm(50, mean = 0.16, sd = 0.002))), as.data.frame(cbind(measurement = "Temp",values = rnorm(50, mean = 24, sd = 1.3))), as.data.frame(cbind(measurement = "Hum", values = rnorm(50, mean = 100, sd = 10))) )))) data_all_c$values<-as.numeric(data_all_c$values)
解答
问题原因
当设置 hide.ns=T 时,stat_pvalue_manual 会过滤掉所有无显著差异(即 p.adj.signif 为 ns)的行。如果某个循环迭代对应的显著性子集 subset(emmeans_c, sex == s & measurement == m) 在过滤后没有任何行剩余,函数就找不到 label 参数指定的列,从而抛出 object 'label' not found 错误。而 hide.ns=F 时,即使所有结果都是ns,数据框也不会被清空,因此能正常运行。
另外,原代码中 ggplot(subset(data_all_c, sex == s | measurement == m)) 存在逻辑错误:用|会同时选中所有该性别或该测量指标的数据,导致数据混乱,应该改成&,只保留当前性别且当前测量指标的数据。
解决方法
在循环中先检查过滤后的显著性数据是否为空,仅当数据非空时才添加显著性标记层:
for(m in unique(data_all_c$measurement)){ for (s in unique(data_all_c$sex)) { # 提取当前迭代的显著性数据并过滤无显著差异的结果 sig_data <- subset(emmeans_c, sex == s & measurement == m) sig_data_filtered <- sig_data[sig_data$p.adj.signif != "ns", ] # 初始化基础图表,修正数据子集逻辑 const <- ggplot(subset(data_all_c, sex == s & measurement == m))+ aes(x = light_c, y = values, fill = group)+ stat_summary(fun.data = mean_se, geom = "bar", position = "dodge")+ stat_summary(fun.data = mean_se, geom = "errorbar", position = position_dodge(width = 0.9),width = 0.2, show.legend = FALSE) # 仅当过滤后的数据非空时添加显著性标记 if(nrow(sig_data_filtered) > 0){ const <- const + stat_pvalue_manual(sig_data_filtered, label = "p.adj.signif", xmin = "xmin", xmax = "xmax", step.group.by = "group1", color = "darkgrey" ,inherit.aes = FALSE) } print(const) } }
内容的提问来源于stack exchange,提问作者Sontje
相关产品推荐
相关产品推荐

