Home > Back-end >  How to use a function to place text in geom_boxplot
How to use a function to place text in geom_boxplot

Time:01-03

I'm working on some boxplots. Here is a working example:

data(mtcars)

# Compute means for each group
mpgmn <- aggregate(mpg ~ cyl, mtcars, mean)
mpgmn$mpg <- round(mpgmn$mpg, 2)

# Same thing for 50th and 75th %tiles
mpglims <- mtcars %>% group_by(cyl) %>% 
        summarize(q50 = quantile(mpg, probs = 0.50), 
                  q75 = quantile(mpg, probs = 0.75))

# Plot
library(ggplot2)
g <- ggplot(mtcars, aes(x = as.factor(cyl), y = mpg, 
     fill = as.factor(cyl)))
g <- g   geom_boxplot()
g <- g   stat_summary(fun = mean, color = "white", geom = "point", 
     shape = 18, size = 3, show.legend = FALSE)
g <- g   geom_text(data = mpgmn, 
     aes(label = paste("mean = ", mpg),
     y = mpg   0.5), color = "white")
g

All of this works. However, I would like to use the mpglims that I computed (that look correct to me) to place the white text inside each of the boxplots (i.e., instead of the current vertical position argument: y = mpg 0.05). Is there a way to tell R to pick the halfway point between the two values that I computed for each group for the vertical position?

CodePudding user response:

The easiest way might be to add one more variable to the creation of mpglims:

mpglims <- mtcars %>% group_by(cyl) %>% 
        summarize(q50 = quantile(mpg, probs = 0.50), 
                  q75 = quantile(mpg, probs = 0.75),
                  mid = (q50   q75)/ 2)

Use mid in y = mid in the geom_text() call.

If you want to use what you calculated in the first data frame mpgmn, make it a bit easier on yourself and add that to mpglims, as well:

mpglims <- mtcars %>% group_by(cyl) %>% 
        summarize(q50 = quantile(mpg, probs = 0.50), 
                  q75 = quantile(mpg, probs = 0.75),
                  mid = (q50   q75)/ 2,
                  mmpg = mean(mpg) %>% round(., digits = 2))

It creates the same thing as your aggregate() call. Check it out:

mpglims[, 5] %>% unlist()
# mmpg1 mmpg2 mmpg3 
# 26.66 19.74 15.10 

CodePudding user response:

Putting all informations already provided by Kat (this answer should be the accepted one) and the OP, here is one possibly tidyverse way:

library(tidyverse)

mtcars %>% 
  select(cyl, mpg) %>% 
  group_by(cyl = as.factor(cyl)) %>% 
  mutate(mpg_mean = round(mean(mpg, na.rm = TRUE),2)) %>% 
  mutate(q50 = quantile(mpg, probs = 0.50), 
         q75 = quantile(mpg, probs = 0.75)) %>% 
  mutate(mid = (q50   q75)/ 2) %>%
  ggplot(aes(x = cyl,  y = mpg, fill = cyl))  
  geom_boxplot()  
  stat_summary(fun = mean, color = "white", geom = "point", 
               shape = 18, size = 3, show.legend = FALSE)  
  geom_text(aes(label = paste("mean = ", mpg_mean),
                y = mid), color = "white")

enter image description here

  • Related