rggplot2boxplotfacet-gridkruskal-wallis

Error adding the Kruskal Wallis pvalue into boxplots with facet_grid in R


I am trying to add the Kruskal Wallis pvalue to my boxplots and although I have seen a lot of posts with the solution, I cannot make it work.

This is my data and the code to run the boxplots:

library(ggplot2)
library(dplyr)
set.seed(1234)
Gene <- floor(runif(25, min=0, max=101))
Age <- floor(runif(25, min=18, max=75))
Group <- c("Group1", "Group1", "Group3", "Group2", "Group1", "Group3", "Group2", "Group2", "Group2", "Group1", "Group1", "Group3", "Group1", "Group2", "Group1", "Group2", "Group3", "Group1", "Group3", "Group3", "Group2", "Group1", "Group3", "Group3","Group2")


df <- data.frame(Gene, Age, Group)

mybreaks <- seq(min(df$Age)-1, to=max(df$Age)+10, by=10)
df$groups_age <- cut(df$Age, breaks = mybreaks, by=10)

bp <- ggplot(df, aes(x=groups_age, y=Gene, group=groups_age)) + 
  geom_boxplot(aes(fill=groups_age)) + 
  facet_grid(. ~ Group)

bp

image 1

In this post, I see one way to do it, but when I try to do the same, I get this error Error in FUN(X[[i]], ...) : object 'groups_age' not found and the plot is not shown.

The code:

pv <- df %>%
  group_by(Group) %>%
  summarize(Kruskal_pvalue = kruskal.test(Gene ~ groups_age)$p.value)

bp <- ggplot(df, aes(x=groups_age, y=Gene, group=groups_age)) + 
  geom_boxplot(aes(fill=groups_age)) + 
  facet_grid(. ~ Group) +
  geom_text(data=pv, aes(x=2, y=75, label=paste0("Kruskal-Wallis\n p=",Kruskal_pvalue)))
bp

Note that I put x and y manually, just to place the value. However, I would like to do it more automatically, depending on the value of the gene if it changes.

Does anyone know why I am getting that error and why it is not working?

Thanks very much in advance

Regards


Solution

  • The issue is that you made group=groups_age a global aesthetic. All layers will inherit the global aes and hence all layers will look for a column called groups_age in the data provided to the layer. As the data pv used in geom_text does not contain a column of this name you get an error.

    To solve your issue you could drop group=groups_age as it is not needed in your case. For more general cases you have to be more specific what you make a local or global aes. Additionally each geom has an inherits.aes argument (which by default is TRUE) to prevent that global aes are inherited:

    library(ggplot2)
    
    bp <- ggplot(df, aes(x = groups_age, y = Gene)) +
      geom_boxplot(aes(fill = groups_age)) +
      facet_grid(. ~ Group) +
      geom_text(data = pv, aes(x = 2, y = 75, label = paste0("Kruskal-Wallis\n p=", Kruskal_pvalue)))
    bp
    

    Created on 2021-12-21 by the reprex package (v2.0.1)