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