You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:25:24