Search code examples
rggplot2stat

Add statistical significance to ggplot with geom_bar by bar


I'm representing a barplot with geom_bar in R that displays two discrete x levels and one continuous y level faceted. I want to put stars to show the significance level (p-value) between the groups stacked in one position. I usually use stat_compare_means to compare between groups, but I cannot represent it when the groups are piled and not next to each other.

My code is similar to the one posted below. I want to add starts on top of each column by comparing the values by B. The statistic that I want to represent is the one calculated below with compare_means

library(tidyverse)
library(ggpubr)

dataplot <-
  data.frame(
    A = rep(c("A1", "A2"), 8),
    B = rep(c(rep("B1", 4), rep("B2", 4)),2),
    C = c(rep("C1",8), rep("C2",8)),
    value = rep(c(1, 5, 2, 6, 8, 15, 9, 16),2)
  ) 


ggplot(dataplot, aes(A, value, fill = B, color = B)) +
  geom_bar(
    position = "identity",
    stat = "summary",
    alpha = .5,
    fun = mean
  ) +
  geom_point(
    aes(x = A),
    size = 2,
    stroke = 0.5,
    position = "jitter"
  )+
  facet_wrap(~C)

compare_means(value ~ B, group.by = c("A", "C"), data = dataplot, method = "t.test") 

This is my plot: plot

This is the obtained stat.

# A tibble: 4 x 10
  A     C     .y.   group1 group2       p p.adj p.format p.signif method
  <chr> <chr> <chr> <chr>  <chr>    <dbl> <dbl> <chr>    <chr>    <chr> 
1 A1    C1    value B1     B2     0.0101   0.02 0.010    *        T-test
2 A2    C1    value B1     B2     0.00496  0.02 0.005    **       T-test
3 A1    C2    value B1     B2     0.0101   0.02 0.010    *        T-test
4 A2    C2    value B1     B2     0.00496  0.02 0.005    **       T-test

And this is what I want:

enter image description here

I already read Put stars on ggplot barplots and boxplots - to indicate the level of significance (p-value), but this solution don't work for me when the groups are pilled, only when they are next to each other


Solution

  • An option is defining the y position of the significant signs by creating a vector. You can use geom_text and label to assign the text on top of your bars like this:

    library(tidyverse)
    library(ggpubr)
    stats <- compare_means(value ~ B, group.by = c("A", "C"), data = dataplot, method = "t.test")
    
    ggplot(dataplot, ) +
      geom_bar(aes(A, value, fill = B, color = B),
        position = "identity",
        stat = "summary",
        alpha = .5,
        fun = mean
      ) +
      geom_point(
        aes(x = A, y = value, fill = B, color = B),
        size = 2,
        stroke = 0.5,
        position = "jitter"
      )+ 
      geom_text(data = stats, aes(x = A, y = c(9, 16, 9, 16), label = p.signif), size = 10) +
      facet_wrap(~C) 
    

    Output:

    enter image description here