1
votes

This question is a follow-up to: Annotating text on individual facet in ggplot2

I was trying out the code provided in the accepted answer and got something that was strangely different than the result provided. Granted the post is older and I'm using R 3.5.3 and ggplot2 3.1.0, but what I'm getting doesn't seem to make sense.

library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ cyl)

#below is how the original post created a dataframe for the text annotation
#this will produce an extra facet in the plot for reasons I don't know
ann_text <- data.frame(mpg = 15,wt = 5,lab = "Text",cyl = factor(8,levels = c("4","6","8")))

p+geom_text(data = ann_text,label = "Text")

This is the code from the accepted answer in the linked question. For me it produces the following graph with an extra facet (i.e, an addition categorical variable of 3 seems to have been added to cyl)

https://github.com/RamenZzz/hello-world/blob/master/Rplot09b.jpeg?raw=true

#below is an alternative version that produces the correct plot, that is,
#without any extra facets.
ann_text_alternate <- data.frame(mpg = 15,wt = 5,lab = "Text",cyl = 8)

p+geom_text(data = ann_text_alternate,label = "Text")

This gives me the correct graph:

https://raw.githubusercontent.com/RamenZzz/hello-world/master/Rplot09a.jpeg

Anybody have any explanations?

1
Run str(ann_text) The last row of the output is $ cyl: Factor w/ 3 levels "4","6","8": 3. So the level "8" is code as the number 3. Since you facet by cyl you have one more value. Another solution is facet_grid(. ~ factor(cyl)).Rui Barradas
@Rui post an answer, maybe. These problems with facets are pretty much common; I once fell into the lap of one, not long ago.M--
@M-M Done. As a matter of fact, I had considered posting as an answer, since sometimes it happens to me too.Rui Barradas

1 Answers

1
votes

What is going on is a factors issue.
First, you facet by cyl, a column in dataset mtcars. This is an object of class "numeric" taking 3 different values.

unique(mtcars$cyl)
#[1] 6 4 8

Then, you create a new dataset, the dataframe ann_text. But you define cyl as an object of class "factor". And what is in this column can be seen with str.

str(ann_text)
#'data.frame':  1 obs. of  4 variables:
# $ mpg: num 15
# $ wt : num 5
# $ lab: Factor w/ 1 level "Text": 1
# $ cyl: Factor w/ 3 levels "4","6","8": 3

R codes factors as integers starting at 1, level "8" is the level number 3.
So when you combine both datasets, there are 4 values for cyl, the original numbers 4, 6 and 8 plus the new number, 3. Hence the extra facet.

This is also the reason why the solution works, in dataframe ann_text_alternate column cyl is a numeric variable taking one of the already existing values.

Another way of making it work would be to coerce cyl to factor when faceting. Note that

levels(factor(mtcars$cyl))
#[1] "4" "6" "8"

And the new dataframe ann_text no longer has a 4th level. Start plotting the graph as in the question

p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ factor(cyl))

and add the text.

p + geom_text(data = ann_text, label = "Text")