缘由

统计是生信的基石之一

碎碎念

要爱一个具体的人,不要爱一个抽象的人; 要爱生活,不要爱生活的意义。 ——《卡拉马佐夫兄弟》

Ref

GGPUBR: How to Add P-Values Generated Elsewhere to a GGPLOT - Datanovia

解读

1. 基础p值标注

手动创建统计结果

library(ggpubr)
df <- ToothGrowth
df$dose <- factor(df$dose)
 
# 手动创建统计检验结果
stat.test <- tibble::tribble(
  ~group1, ~group2,   ~p.adj,
  "0.5",     "1", 2.54e-07,
  "0.5",     "2", 1.32e-13,
  "1",     "2", 1.91e-05
)
stat.test
 
# 基础箱线图添加p值
ggboxplot(df, x = "dose", y = "len") +
  stat_pvalue_manual(
    stat.test, 
    y.position = 35, step.increase = 0.1,
    label = "p.adj"
  )
  • stat_pvalue_manual(): 手动添加p值标注
  • y.position: 设置p值标注的垂直位置
  • step.increase: 多个比较间的垂直间距
  • label: 指定显示p值还是显著性星号

自动统计检验与标注

# 自动进行t检验
stat.test <- df %>% t_test(len ~ dose)
stat.test
 
# 自动计算标注位置并添加显著性星号
stat.test <- stat.test %>% add_xy_position(x = "dose")
bxp + stat_pvalue_manual(stat.test, label = "p.adj.signif", tip.length = 0.01)

2. 分组分析与分面标注

以参考组为基础的多重比较

# 在每个supp组内,以0.5剂量为参考进行比较
stat.test <- df %>%
  group_by(supp) %>%
  t_test(len ~ dose, ref.group = "0.5")
stat.test
 
# 分面显示并添加p值
stat.test <- stat.test %>% add_xy_position(x = "dose")
ggboxplot(df, x = "dose", y = "len", facet.by = "supp") +
  stat_pvalue_manual(stat.test, label = "p.adj.signif", tip.length = 0.01)

复杂分组布局

# 分组t检验
stat.test <- df %>%
  group_by(supp) %>%
  t_test(len ~ dose, ref.group = "0.5") 
 
# 分组箱线图与p值标注
stat.test <- stat.test %>% 
  add_xy_position(x = "supp", dodge = 0.8)  # dodge参数控制位置偏移
bxp <- ggboxplot(df, x = "supp", y = "len", color = "dose")
bxp + stat_pvalue_manual(stat.test, label = "p.adj", tip.length = 0.01)
  • ref.group: 指定参考组进行多重比较
  • dodge: 在分组图中调整p值标注的水平位置

3. 手动位置控制与高级定制

精确控制y轴位置

# 手动指定每个比较的y轴位置
stat.test <- ToothGrowth %>%
  t_test(len ~ dose) %>%
  mutate(y.position = c(29, 35, 39))  # 分别为三个比较指定位置
stat.test

分面图中的组内比较

# 在每个剂量水平比较supp
stat.test <- df %>%
  group_by(dose) %>%
  t_test(len ~ supp) %>%
  adjust_pvalue() %>%
  mutate(y.position = 35)  # 统一y轴位置
 
p <- ggboxplot(
  df, x = "supp", y = "len",
  color = "supp", palette = "jco",
  facet.by = "dose", ylim = c(0, 40)
)
p + stat_pvalue_manual(stat.test, label = "p.adj")

4. 水平连接线与高级定位

使用xmin参数创建水平连接

stat.test <- df %>%
  group_by(dose) %>%
  t_test(len ~ supp) %>%
  adjust_pvalue() %>%
  mutate(y.position = 35)
 
p <- ggboxplot(
  ToothGrowth, x = "dose", y = "len",
  color = "supp", palette = "jco",
  ylim = c(0, 40)
)
 
# 使用xmin创建水平方向的p值标注
p + stat_pvalue_manual(stat.test, xmin = "dose", xmax = NULL)

5. geom_bracket函数:更灵活的标注

基础括号标注

# 使用geom_bracket手动添加括号和标注
ggboxplot(df, x = "dose", y = "len") +
  geom_bracket(
    xmin = "0.5", xmax = "1", y.position = 30,
    label = "t-test, p < 0.05"
  )

自定义外观

# 调整尖端长度和标签位置
ggboxplot(df, x = "dose", y = "len") +
  geom_bracket(
    xmin = "0.5", xmax = "1", y.position = 30,
    label = "t-test, p < 0.05", 
    tip.length = c(0.2, 0.02),  # 左右尖端长度
    vjust = -1  # 垂直调整标签位置
  )

数学表达式标注

# 使用plotmath表达式创建学术风格的p值标注
ggboxplot(df, x = "dose", y = "len") +
  geom_bracket(
    xmin = "0.5", xmax = "1", y.position = 30,
    label = "list(~italic(p)<=0.001)", 
    type = "expression",  # 指定为表达式类型
    tip.length = c(0.2, 0.02)
  )

多重括号标注

# 一次性添加多个比较的括号
ggboxplot(df, x = "dose", y = "len") +
  geom_bracket(
    xmin = c("0.5", "1"), xmax = c("1", "2"),
    y.position = c(30, 35), label = c("***", "**"),
    tip.length = 0.01
  )

6. 与compare_means集成

自动化工作流

# 使用compare_means自动完成检验和标注
stat.test <- compare_means(len ~ dose, ToothGrowth, method = "t.test")
ggboxplot(df, x = "dose", y = "len") +
  geom_bracket(
    aes(xmin = group1, xmax = group2, label = signif(p, 2)),
    data = stat.test, y.position = 35
  )

高级布局控制

# 增加括号间距
ggboxplot(df, x = "dose", y = "len") +
  geom_bracket(
    aes(xmin = group1, xmax = group2, label = signif(p, 2)),
    data = stat.test, y.position = 35, step.increase = 0.1
  )
 
# 或精确指定每个比较的位置
ggboxplot(df, x = "dose", y = "len") +
  geom_bracket(
    aes(xmin = group1, xmax = group2, label = signif(p, 2)),
    data = stat.test, y.position = c(32, 35, 38)
  )