How to add number of observation and Median per group in boxplot in ggplot2

Viewed 97

Probably my question may be a duplicate, but I am unable to do it in ggplot2 (tidyverse) only?

I want to add count of number of observations and median to each group/element of a box-plot in ggplot2

Here is the reprex

library(tidyverse)

set.seed(123)

df <- iris %>% sample_n(100)

df %>% 
  mutate(grp = ifelse(Sepal.Width > mean(Sepal.Width), 'Gr-1', 'Gr-2')) %>%
  ggplot(aes(x = Species, y = Sepal.Length, fill = grp)) +
  geom_boxplot() +
  coord_flip() +
  facet_wrap(. ~ grp)

Created on 2021-06-24 by the reprex package (v2.0.0)

Expected outcome something like this for all 6 boxes

enter image description here

1 Answers

I think you can use the following solution taken from an article. For this purpose we can make use of stat_summary function, but for its fun.data we have to create a custom function that calculates count and median. It should be noted that we use geom_text in stat_summary so it requires x or y and label argument. So when we write our custom stat_box_sum function we have to make sure that the resulting data frame has these aesthetics as column names:

stat_box_sum <- function(y, upper_limit = max(iris$Sepal.Length)) {
  DF <- data.frame(
    y = max(y),
    label = paste("N:", length(y), "\n",
                  "Median:", median(y), "\n")
  )
  DF
}

stat_box_sum(iris$Sepal.Length)
    y                    label
1 7.9 N: 150 \n Median: 5.8 \n

df %>% 
  mutate(grp = ifelse(Sepal.Width > mean(Sepal.Width), 'Gr-1', 'Gr-2')) %>%
  ggplot(aes(x = Species, y = Sepal.Length, fill = grp)) +
  geom_boxplot() +
  coord_flip() +
  facet_wrap(. ~ grp) + 
  stat_summary(
    fun.data = stat_box_sum, 
               geom = "text", 
    hjust = 0.7,
    vjust = 0.7)

enter image description here The only remaining problem I suppose is the adjustment of labels which I try to figure out soon.

Related