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

如何修改stat_compare_means中部分组比较的p值小数位数?

问题:自定义stat_compare_means部分组比较的p值小数位数

我知道有类似问题,但尝试相关方案后还是没法修改stat_compare_means里的p值小数位数,推测是因为我只做部分组的两两比较,而非全组比较。我试过在label里加decimal=3,或者自定义format.pval = function(p) format(p, digits = 3),要么没效果要么报错。

我的代码如下:

library(tidyverse)
library(ggbeeswarm)
library(ggpubr)

set.seed(123) 

data <- data.frame(
 plot = rep(c("cl", "ct", 
              "rt", "rl"), each = 10),
 value = c(rnorm(10, mean = 3.5, sd = 0.3),   # Control lower canopy
          rnorm(10, mean = 3.7, sd = 0.3),   # Control upper canopy
          rnorm(10, mean = 4.0, sd = 0.3),   # Released upper canopy
          rnorm(10, mean = 4.2, sd = 0.3))   # Released lower canopy
)

summary_data <- data %>%
 group_by(plot) %>%
 summarise(
  value_Mean = mean(value),
  value_SE = sd(value) / sqrt(n())
 )

comparisons <- list(
 c("cl", "ct"),
 c("ct", "rt"),
 c("rt", "rl"),
 c("cl", "rl")
)

ggplot(data, aes(x = plot, y = value)) +
 geom_beeswarm(aes(color = plot),size = 5, alpha = 0.6) +
 geom_errorbar(
  data = summary_data, 
  aes(y = value_Mean, ymin = value_Mean - value_SE, ymax = value_Mean + value_SE),
  width = 0.2, size = 0.8, color = "black"
 ) +
 geom_point(
  data = summary_data, 
  aes(y = value_Mean), color = "red", size = 8
 ) +
 stat_compare_means(
  comparisons = comparisons, method = "t.test", label = "p.format", 
  label.y = c(4.3, 4.8, 5.3, 5.8), 
  size = 10
 )

解决方法

方法1:使用formatter参数指定格式化函数

针对label = "p.format"的场景,直接通过formatter参数传递自定义的p值格式化函数即可,这是最简洁的方式:

ggplot(data, aes(x = plot, y = value)) +
 geom_beeswarm(aes(color = plot),size = 5, alpha = 0.6) +
 geom_errorbar(
  data = summary_data, 
  aes(y = value_Mean, ymin = value_Mean - value_SE, ymax = value_Mean + value_SE),
  width = 0.2, size = 0.8, color = "black"
 ) +
 geom_point(
  data = summary_data, 
  aes(y = value_Mean), color = "red", size = 8
 ) +
 stat_compare_means(
  comparisons = comparisons, method = "t.test", label = "p.format", 
  label.y = c(4.3, 4.8, 5.3, 5.8), 
  size = 10,
  # 自定义p值格式化,保留3位有效数字,小于0.001时显示<0.001
  formatter = function(p) format.pval(p, digits = 3, eps = 0.001)
 )
  • digits:控制p值的有效位数,这里设为3
  • eps:当p值小于该阈值时,显示为<eps,可根据需求调整(比如设为0.0001则显示<0.0001)

方法2:预先计算p值,手动添加文本

如果方法1不生效,可以先手动计算所有比较的p值,格式化后用geom_text添加到图中,灵活性更高:

# 计算所有指定组比较的p值
p_vals <- purrr::map_dbl(comparisons, function(x) {
  t.test(data$value[data$plot == x[1]], data$value[data$plot == x[2]])$p.value
})
# 格式化p值
formatted_p <- format.pval(p_vals, digits = 3, eps = 0.001)

# 绘制图形,替换stat_compare_means为geom_text
ggplot(data, aes(x = plot, y = value)) +
 geom_beeswarm(aes(color = plot),size = 5, alpha = 0.6) +
 geom_errorbar(
  data = summary_data, 
  aes(y = value_Mean, ymin = value_Mean - value_SE, ymax = value_Mean + value_SE),
  width = 0.2, size = 0.8, color = "black"
 ) +
 geom_point(
  data = summary_data, 
  aes(y = value_Mean), color = "red", size = 8
 ) +
 geom_text(
  # 计算每组比较的x轴位置(两组的中间点)
  x = purrr::map_dbl(comparisons, function(x) mean(which(levels(data$plot) %in% x))),
  y = c(4.3, 4.8, 5.3, 5.8),
  label = formatted_p,
  size = 10
 )

为什么之前的方法无效?

  • 直接在label参数中添加decimal=3是错误用法:label仅接受预定义的字符串(如"p.format"、"p.signif"),不支持额外参数。
  • 自定义format.pval函数时,若未通过formatter参数传递给stat_compare_means,函数不会被调用,导致报错或无效果。

内容的提问来源于stack exchange,提问作者Gonzalo de Quesada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:56:08