Rótulos do eixo x de várias linhas no gráfico de linhas ggplot

Edit: Esta questão foi marcada como duplicada, mas as respostas aqui foram tentadas e não funcionaram porque o caso em questão é um gráfico de linhas, não um gráfico de barras. A aplicação desses methods produz um gráfico com 5 linhas, 1 para cada ano – não é útil. Alguém que votou para marcar como duplicado realmente tentou essas abordagens no dataset de amostra fornecido com essa pergunta? Em caso afirmativo, poste como uma resposta.

Pergunta original:

Há um recurso em charts dynamics do Excel que permite eixos categóricos de vários níveis. Estou tentando encontrar uma maneira de fazer a mesma coisa com ggplot (ou qualquer outro pacote de plotagem em R).

Considere o seguinte dataset:

 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)) 

Se isso for importado para uma tabela dinâmica do Excel, é fácil criar o seguinte gráfico:

Observe como o eixo x tem dois níveis, um para o trimestre e outro para a variável de agrupamento, ano. Os eixos multiníveis são possíveis com o ggplot ?

NB: Há um hack com facetas que produz algo semelhante, mas isso não é o que eu estou procurando.

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

Usamos argumentos no theme para remover o texto padrão do eixo x ( axis.title.x / axis.text.x = element_blank() ) e margens extras são adicionadas ( plot.margin ).

Novos labels são adicionados usando annotate(geom = "text", . Ao converter o object de plotagem em um grob ( ggplot_gtable(ggplot_build( ), o recorte de labels do eixo x pode ser desativado.

 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) 

insira a descrição da imagem aqui


Veja também a boa resposta de @ eipi10 aqui: labels Axis em duas linhas com variables ​​x aninhadas (ano abaixo dos meses)

O código sugerido por Henrik funciona e me ajudou muito! Eu acho que a solução tem um valor alto. Mas esteja ciente de que há um pequeno erro na primeira linha do código, o que resulta em uma ordem incorreta dos dados. Ao invés de

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

deveria ser

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

O gráfico resultante tem os dados na ordem correta.

insira a descrição da imagem aqui

PS Eu sugeri uma edição (que foi rejeitada até agora) e, devido a uma pequena falta de reputação, não posso comentar, o que eu preferiria fazer.