1

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
yanxianl
  • 13
  • 1
  • 6
  • any sample output plots? – sai saran Nov 09 '18 at 13:34
  • In terms of the error message: Right now you have `fill = Rank` in the global aesthetics in `ggplot()`, so `geom_signif()` goes looking for this variable in the `anno` dataset and can't find it and so tells you. You can either move `fill` into the layer you use it on (`geom_bar`) or use `fill = NULL` in `geom_signif`. – aosmith Nov 09 '18 at 14:12
  • Hi @aosmith, your solutions solved the problem as well. Thank you! – yanxianl Nov 12 '18 at 13:52

1 Answers1

1

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

enter image description here

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))

enter image description here

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)
                 )
Roman
  • 17,008
  • 3
  • 36
  • 49