43

Following this question: How to add a number of observations per group and use group mean in ggplot2 boxplot?, I want to add number of observations per group in ggplot boxplot, too. But I have added a colour into aes mapping.

The existing answer shows how to adjust text position in y axis. How could I adjust the text position in the x axis?

This is a minimum example to reproduce my problem:

library(ggplot2)

give.n <- function(x){
  return(c(y = median(x)*1.05, label = length(x))) 
  # experiment with the multiplier to find the perfect position
}


p <- ggplot(mtcars, aes(factor(vs), mpg, colour = factor(am))) + 
    geom_boxplot() +
    stat_summary(fun.data = give.n, geom = "text", fun.y = median)
p

enter image description here

2 Answers 2

30

You can just use position:

p <- ggplot(mtcars, aes(factor(vs), mpg, colour = factor(am))) +  
     geom_boxplot() +
     stat_summary(fun.data = give.n, geom = "text", fun.y = median,
                  position = position_dodge(width = 0.75))
p

enter image description here

The width argument of position_dodge() controls the positioning on the horizontal axis. 0.75 is the sweet spot, see how it works for different numbers of groupings:

p2 <- ggplot(mtcars, aes(factor(vs), mpg, colour = factor(cyl))) + 
      geom_boxplot() +
      stat_summary(fun.data = give.n, geom = "text", fun.y = median, 
                   position = position_dodge(width = 0.75))
p2

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

3

Instead of stat_summary, you can use geom_text. Please refer to the following question: ggplot2 add text on top of boxplots.

This is an example of how you may do it with the number of observations:

# Create an aggregate of median & count
> cts <- merge(aggregate(mpg ~ cyl + am, mtcars, length), 
               aggregate(mpg ~ cyl + am, mtcars, median), 
               by=c("cyl", "am"))
# Rename the col names to fit with the original dataset..
> names(cts) <- c("cyl", "am", "count", "mpg")
# As alexwhan suggested, position_dodge helps with positioning
# along the x-axis..
> ggplot(mtcars, aes(factor(cyl), mpg, colour = factor(am))) + 
  geom_boxplot(position = position_dodge(width=1.0)) + 
  geom_text(data = cts, aes(label=count), 
            position=position_dodge(width=1.0))

2 Comments

geom_text does not seem to do counts by groups. Can you show the code how to do this with geom_text?
geom_text is a text labeling function, it doesn't do any aggregations or summary statistics on the data. But you can create an aggregate of the dataset that calculates the count per group, and use that as an input to geom_text. I edited my answer to provide an example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.