Etiquetas de eje x de múltiples filas en el gráfico de líneas ggplot

Editar: esta pregunta se ha marcado como duplicada, pero las respuestas aquí se han intentado y no funcionaron porque el caso en cuestión es un gráfico de líneas, no un gráfico de barras. La aplicación de esos métodos produce un cuadro con 5 líneas, 1 por cada año, no es útil. ¿Alguien que votó para marcar como duplicado en realidad prueba esos enfoques en el conjunto de datos de muestra suministrados con esta pregunta? Si es así, publique como respuesta.

Pregunta Original:

Hay una característica en los gráficos dynamics de Excel que permite ejes categóricos multinivel. Estoy tratando de encontrar la manera de hacer lo mismo con ggplot (o cualquier otro paquete de trazado en R).

Considere el siguiente conjunto de datos:

 set.seed(1) df=data.frame(year=rep(2009:2013,each=4), quarter=rep(c("Q1","Q2","Q3","Q4"),5), sales=40:59+rnorm(20,sd=5)) 

Si esto se importa a una tabla dinámica de Excel, es sencillo crear la siguiente tabla:

Observe cómo el eje x tiene dos niveles, uno por trimestre y uno por la variable de agrupación, año. ¿Son posibles los ejes multinivel con ggplot ?

NB: Hay un truco con facetas que produce algo similar, pero esto no es lo que estoy buscando.

 library(ggplot2) ggplot(df) + geom_line(aes(x=quarter,y=sales,group=year))+ facet_grid(.~year,scales="free") 

Usamos argumentos en el theme para eliminar el texto predeterminado del eje x ( axis.title.x / axis.text.x = element_blank() ) y se agregan márgenes adicionales ( plot.margin ).

Las nuevas tags se agregan usando annotate(geom = "text", ,. Al convertir el objeto de trazado en grob ( ggplot_gtable(ggplot_build( ), se puede desactivar el recorte de las tags del eje x.

 library(ggplot2) g1 <- ggplot(data = df, aes(x = interaction(year, quarter, lex.order = TRUE), y = sales, group = 1)) + geom_line(colour = "blue") + coord_cartesian(ylim = c(35, 65), expand = FALSE) + annotate(geom = "text", x = seq_len(nrow(df)), y = 34, label = df$quarter, size = 4) + annotate(geom = "text", x = 2.5 + 4 * (0:4), y = 32, label = unique(df$year), size = 6) + theme_bw() + theme(plot.margin = unit(c(1, 1, 4, 1), "lines"), axis.title.x = element_blank(), axis.text.x = element_blank(), panel.grid.major.x = element_blank(), panel.grid.minor.x = element_blank()) # remove clipping of x axis labels g2 <- ggplot_gtable(ggplot_build(g1)) g2$layout$clip[g2$layout$name == "panel"] <- "off" grid::grid.draw(g2) 

enter image description here


Vea también la buena respuesta de @ eipi10 aquí: Etiquetas de ejes en dos líneas con variables x anidadas (año debajo de meses)

¡El código sugerido por Henrik funciona y me ayudó mucho! Creo que la solución tiene un alto valor. Pero tenga en cuenta que hay un pequeño error en la primera línea del código, lo que da como resultado un orden incorrecto de los datos. En lugar de

 ... aes(x = interaction(year,quarter), ... 

debería ser

 ... aes(x = interaction(quarter,year), ... 

El gráfico resultante tiene los datos en el orden correcto.

enter image description here

PD: sugerí una edición (que fue rechazada hasta ahora) y, debido a una pequeña falta de reputación, no puedo comentar, lo que hubiera preferido hacer.