Annotate in ggplot2 following position_dodge()?

Viewed 601

I'm trying to produce a figure of a two-factorial experiment in R. This contains three levels, and each level has two sub-levels. I want to annotate each of these groups, but I cannot find a reasonable way to do it.

Here's an example producing annotations for the top level:

ggplot(mtcars, aes(x = as.factor(cyl), y = mpg)) +
  geom_point(aes(colour = as.factor(am)), position = position_dodge(0.5)) +
  annotate("text", x = 1:3, y = c(37, 25, 22),
           label = c("a", "b", "c"))

What I really want to do it to annotate each level of 'am' as well.

Here's my naive attempt to do so:

ggplot(mtcars, aes(x = as.factor(cyl), y = mpg)) +
  geom_point(aes(colour = as.factor(am)), position = position_dodge(0.5)) +
  annotate("text", x = 1:6, y = c(27, 37, 25, 25, 22, 17),
           label = c("a", "b", "c", "d", "e", "f"), position = position_dodge(0.5))

> Error: Unequal parameter lengths: x (6), y (6), label (6), position (3)

I have tried varying the number of x, y, and labels. I suspect the answer lies in assigning 'am' levels to the annotations, but I have no idea how to do that. Anyone have a workable solution?

2 Answers

Maybe try geom_text instead ?

library(ggplot2)

ggplot(mtcars, aes(x = cyl, y = mpg)) +
  geom_point(aes(colour = as.factor(am)), position = position_dodge(0.5)) +
  geom_text(data = data.frame(x = c(3.8, 4.2, 5.8, 6.2, 7.8, 8.2), 
                              y = c(27, 37, 25, 25, 22, 17)), 
  aes(x, y, label = c("a", "b", "c", "d", "e", "f")))

enter image description here

Instead of hardcoding label positions, pre-calculate y values, and use aes and group to map x positions.

# calculate desired y positions for cyl * am combinations, e.g. max 
d <- aggregate(mpg ~ am cyl, data = mtcars, max)

# some toy labels
d$lab <- letters[1:nrow(d)]

# calculate desired y positions for cyl groups, e.g. mean of am max
d2 <- aggregate(mpg ~ cyl, data = d, mean)

# some toy labels
d2$lab <-LETTERS[1:nrow(d2)]

pd <- position_dodge(width = 0.5)

ggplot(mtcars, aes(x = factor(cyl), y = mpg)) +
  geom_point(aes(colour = factor(am)), position = pd) + 
  geom_text(data = d, aes(y = mpg + 1, label = lab, group = factor(am)), position = pd) +
  geom_text(data = d2, aes(label = lab))

enter image description here

Related