Problema al pasar variable con notación de signo de dólar ($) a aes () en combinación con facet_grid () o facet_wrap ()

Estoy haciendo un análisis en ggplot2 en este momento para un proyecto y, por casualidad, me encontré con algo (para mí) comportamiento extraño que no puedo explicar. Cuando escribo aes(x = cyl, ...) la ttwig se ve diferente a lo que hace si paso la misma variable usando aes(x = mtcars$cyl, ...) . Cuando facet_grid(am ~ .) Ambos gráficos son iguales nuevamente. El siguiente código se basa en el código de mi proyecto que genera el mismo comportamiento:

 library(dplyr) library(ggplot2) data = mtcars test.data = data %>% select(-hp) ggplot(test.data, aes(x = test.data$cyl, y = mpg)) + geom_point() + facet_grid(am ~ .) + labs(title="graph 1 - dollar sign notation") ggplot(test.data, aes(x = cyl, y = mpg)) + geom_point()+ facet_grid(am ~ .) + labs(title="graph 2 - no dollar sign notation") 

Aquí está la imagen del gráfico 1:

gráfico 1 - notación de signo de dólar

Aquí está la imagen del gráfico 2:

gráfico 2 - sin anotación de signo de dólar

Descubrí que puedo evitar este problema usando aes_string lugar de aes y pasando los nombres de las variables como cadenas, pero me gustaría entender por qué ggplot se comporta de esa manera. El problema también ocurre en bashs similares con facet_wrap .

¡Mucho por cualquier ayuda de antemano! Me siento muy incómodo si no lo entiendo bien …

tl; dr

Nunca use [ o $ dentro de aes() .


Considere este ejemplo ilustrativo donde la variable de faceta f está deliberadamente en un orden no obvio con respecto a x

 d <- data.frame(x=1:10, f=rev(letters[gl(2,5)])) 

Ahora contraste lo que sucede con estas dos plots,

 p1 <- ggplot(d) + facet_grid(.~f, labeller = label_both) + geom_text(aes(x, y=0, label=x, colour=f)) + ggtitle("good mapping") p2 <- ggplot(d) + facet_grid(.~f, labeller = label_both) + geom_text(aes(d$x, y=0, label=x, colour=f)) + ggtitle("$ corruption") 

enter image description here

Podemos tener una mejor idea de lo que sucede al mirar el dataframe creado internamente por ggplot2 para cada panel,

  ggplot_build(p1)[["data"]][[1]][,c("x","PANEL")] x PANEL 1 6 1 2 7 1 3 8 1 4 9 1 5 10 1 6 1 2 7 2 2 8 3 2 9 4 2 10 5 2 ggplot_build(p2)[["data"]][[1]][,c("x", "PANEL")] x PANEL 1 1 1 2 2 1 3 3 1 4 4 1 5 5 1 6 6 2 7 7 2 8 8 2 9 9 2 10 10 2 

El segundo gráfico tiene una asignación incorrecta, porque cuando ggplot crea un data.frame para cada panel, elige x valores en el orden "incorrecto".

Esto ocurre porque el uso de $ rompe el vínculo entre las diversas variables que se deben mapear (ggplot debe suponer que es una variable independiente, que por lo que sabe, podría provenir de una fuente arbitraria desconectada). Como el data.frame en este ejemplo no está ordenado de acuerdo con el factor f , los subconjuntos data.frames utilizados internamente para cada panel asumen un orden incorrecto.