How to Add P Values to Stacked Bar Plot Using Ggsignif Package?

I was trying to add significant p values to a faceted stacked bar plot using ggsignif package but got an error message saying

Error in check_factor(f) : object 'Rank' not found

Any suggestions on how to solve this problem are greatly appreciated! Below are the data and code to reproduce my problem:

library(tidyverse) 
library(cowplot) 
#> 
#> Attaching package: 'cowplot'
#> The following object is masked from 'package:ggplot2':
#> 
#>     ggsave
library(ggsignif) 

# Make a dataframe for plotting stacked bar plot
df <- data.frame(Diet = rep(c("REF", "IM"), each = 8),
                 Variable = c("hpv", "hpv", "hpv", "hpv", "smc", "smc", "lpc", "lpc",
                              "hpv", "hpv", "hpv", "smc", "smc", "smc", "lpc", "lpc"),
                 Rank = c("Mild", "Moderate", "Marked", "Severe", "Normal", "Mild", "Normal", "Mild",
                          "Mild", "Moderate", "Marked", "Normal", "Mild", "Moderate", "Normal", "Mild"),
                 Percent = c(5.56, 38.9, 44.4, 11.1, 38.9, 61.1, 77.8, 22.2, 
                             16.7, 66.7, 16.7, 11.1, 72.2, 16.7, 50, 50)
                 )

# Specify the desired orders of factors and convert "Rank" to an ordered factor
df$Diet <- factor(df$Diet, levels = c("REF", "IM"))
df$Variable <- factor(df$Variable, levels = c("hpv", "smc", "lpc"))
df$Rank <- ordered(df$Rank, levels = c("Normal", "Mild", "Moderate", "Marked", "Severe")) # Rank as ordered factor

# Define color scheme 
my_col = c(Normal = "royalblue2", Mild = "peachpuff1", Moderate = "tan1", Marked = "tomato", Severe = "red3")

# Make stacked barplot 
p <- ggplot(df, aes(Diet, Percent, fill = forcats::fct_rev(Rank))) + # forcats::fct_rev() reverses stacked bars
  geom_bar(stat = "identity") +
  facet_wrap(~ Variable, nrow = 1) +
  scale_fill_manual(values = my_col) + 
  scale_y_continuous(limits = c(0, 105), breaks = 0:5*20, expand = expand_scale(mult = c(0, 0.05))) +
  labs(title = "Stacked bar plot", y = "%") +
  guides(fill = guide_legend(title = "Rank")) + 
  theme_cowplot()

# Make a datafraome for p value annotation
anno <- data.frame(Variable = "hpv",
                   p = 0.03,
                   start = "REF",
                   end = "IM",
                   y = 102)

# Add p value to the plot
p + geom_signif(data = anno,
                aes(xmin = start, 
                    xmax = end, 
                    annotations = p, 
                    y_position = y),
                textsize = 4, 
                tip_length = 0,
                manual = TRUE)
#> Warning: Ignoring unknown aesthetics: xmin, xmax, annotations, y_position
#> Error in check_factor(f): object 'Rank' not found
3

1 Answer

You can try

p <- ggplot(df, aes(Diet, Percent, fill = Rank)) + 
  geom_col() +
  facet_wrap(~ Variable) +
  geom_signif(annotations = 0.03, y_position = 105 ,xmin="IM", xmax="REF")
p

Adding annotation in the other facet you have to hardcode the data behind the plot using code from here How to annotate different values for each facet (bar plot) on R?

p <- ggplot_build(p)
p$data[[2]] <- rbind(p$data[[2]],p$data[[2]]) # rbind a second annotation a three rows
p$data[[2]]$PANEL[4:6] <- 2 # panel 2
p$data[[2]]$annotation[4:6] <- "your text" 
plot(ggplot_gtable(p))

I used ggsignif_0.4.0 & ggplot2_3.0.0 Data

df <- data.frame(Diet = rep(c("REF", "IM"), each = 8),
                 Variable = c("hpv", "hpv", "hpv", "hpv", "smc", "smc", "lpc", "lpc",
                              "hpv", "hpv", "hpv", "smc", "smc", "smc", "lpc", "lpc"),
                 Rank = c("Mild", "Moderate", "Marked", "Severe", "Normal", "Mild", "Normal", "Mild",
                          "Mild", "Moderate", "Marked", "Normal", "Mild", "Moderate", "Normal", "Mild"),
                 Percent = c(5.56, 38.9, 44.4, 11.1, 38.9, 61.1, 77.8, 22.2, 
                             16.7, 66.7, 16.7, 11.1, 72.2, 16.7, 50, 50)
                 )
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Alexander Ross

Alexander Ross

Gaming, Esports & Interactive Media Writer

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.

Share this article
Twitter Facebook Pinterest