shirewoman2
shirewoman2

Reputation: 1928

geom_text with facet_wrap in ggplot2 when group specified

When using ggplot2 to make faceted plots, I'm having trouble getting individual labels in each facet when I also specify a grouping parameter. Without specifying group = ..., things work fine, but I'm trying to make plots of paired data that emphasize the before vs. after treatment changes.

Here is an example:

library(tidyr)
library(ggplot2)

set.seed(253)
data <- data.frame(Subject = LETTERS[1:10],
                   Day1.CompoundA = rnorm(10, 4, 2),
                   Day2.CompoundA = rnorm(10, 7, 2),
                   Day1.CompoundB = rnorm(10, 5, 2),
                   Day2.CompoundB = rnorm(10, 5.5, 2))

# Compare concentration of compounds by day
A <- t.test(data$Day1.CompoundA, data$Day2.CompoundA, paired = TRUE)
B <- t.test(data$Day1.CompoundB, data$Day2.CompoundB, paired = TRUE)

data.long <- gather(data, key = DayCompound, value = Concentration, -Subject) %>%
      separate(DayCompound, c("Day", "Compound"))

# text to annotate graphs
graphLabels <- data.frame(Compound = c("CompoundA", "CompoundB"),
                          Pval = paste("p =", c(signif(A$p.value, 2), 
                                                signif(B$p.value, 2))))

Ok, now that the data are set up, I can make a boxplot just fine:

ggplot(data.long, aes(x = Day, y = Concentration)) +
      geom_boxplot() +
      facet_wrap(~ Compound) +
      geom_text(data = graphLabels, aes(x = 1.5, y = 10, label = Pval))

boxplot example

But if I want to show line plots that emphasize the paired nature of the data by showing each subject in a different color, the facet labels don't work.

ggplot(data.long, aes(x = Day, y = Concentration, color = Subject, group = Subject)) +
      geom_point() + geom_line() +
      facet_wrap(~ Compound) +
      geom_text(data = graphLabels, aes(x = 1.5, y = 10, label = Pval))

# Error in eval(expr, envir, enclos) : object 'Subject' not found

Any suggestions?

Upvotes: 14

Views: 16313

Answers (1)

joran
joran

Reputation: 173517

When you map aesthetics (i.e. aes(...,color = Subject)) in the top level ggplot() call, those mappings are passed on to each layer, which means that each layer expects data to have variables by those names.

You either need to specify the data and mapping separately in each layer, or unmap them explicitly:

ggplot(data.long, aes(x = Day, y = Concentration, color = Subject, group = Subject)) +
    geom_point() + geom_line() +
    facet_wrap(~ Compound) +
    geom_text(data = graphLabels, aes(x = 1.5, y = 10, label = Pval,color = NULL,group= NULL))

There is also an inherit.aes argument that you can set to FALSE in any layer you don't want pulling in those other mappings, e.g.

ggplot(data.long, aes(x = Day, y = Concentration, color = Subject, group = Subject)) +
    geom_point() + geom_line() +
    facet_wrap(~ Compound) +
    geom_text(data = graphLabels, aes(x = 1.5, y = 10, label = Pval),inherit.aes = FALSE)

Upvotes: 24

Related Questions