Cómo reordenar una variable en ggplot

Llegamos ya a la recta final del Calendario de adviento 2021 especial ggplot. Hasta el momento hablamos de algunos de los aspectos eseciales de un gráfico como son el título, la leyenda, el color o el tema del gráfico, pero se nos escapa uno de los principales asuntos en visualización de datos: los ejes.
En esta serie de posts veremos cómo reordenar una variable asociada a un eje, cómo trabajar con el formato fecha en los ejes y cómo añadir unidades a los ejes.
Hoy empezamos por una de las búsquedas más recurrentes en Google, cómo reordenar una variable en ggplot. Empezamos!
Primero, partimos del gráfico de barras que representa el número medio de horas de sueño de un mamífero clasificado por el tipo de alimentación.
library(dplyr)
library(ggplot2)
library(showtext)
font_add_google('Anton')
msleep$vore[is.na(msleep$vore)] <- 'desconocido'
msleep$vore <- as.factor(msleep$vore)
levels(msleep$vore) <- c('carnívoro', 'desconocido', 'herbívoro', 'insectívoro', 'omnívoro')
msleep %>%
group_by(vore) %>%
summarise(avg_sleep:=mean(sleep_total)) %>%
ggplot(aes(x=vore, y=avg_sleep)) +
geom_col(fill='#222222') +
theme_minimal() +
labs(title='El sueño de los mamíferos',
subtitle='Media de horas de sueño por tipo de mamífero según alimentación',
caption='Proceedings of the National Academy of Sciences, 104 (3):1051-1056, 2007',
x='', y='') +
theme(legend.position='none',
text=element_text(family='Anton'),
plot.title=element_text(family='Anton', size=20),
plot.subtitle=element_text(family='Anton'),
axis.title.x = element_text(family='Anton', face='bold', hjust=1),
axis.title.y = element_text(family='Anton', face='bold', hjust=1),
strip.text=element_text(family='Anton', face='bold', size=14, hjust=0, color='white'),
strip.background=element_rect(fill='black'))
Por defecto, el eje x está ordenado de forma alfabética, siguiendo el orden del factor. En caso, de trabajar con una variable de tipo character, ggplot también seguiría el orden alfabético.
Sin embargo, en un gráfico de barras la información se suele ordenar según la variable cuantitativa representada, en este caso, las horas de sueño medio que el tipo de animal duerme. Por lo que podríamos:
-
Bien reordenar el factor en el propio dataset a través de la función
factor()
y el argumentolevels
. -
O bien reordenar la variable dentro de ggplot directamente con la función
reorder()
.
La segunda opción es la más aconsejable ya que no modifica el dataset original y afecta sólo al gráfico, lo cuál es la intención última de la ordenación.
msleep %>%
group_by(vore) %>%
summarise(avg_sleep:=mean(sleep_total)) %>%
ggplot(aes(x=reorder(vore, desc(avg_sleep)), y=avg_sleep)) +
geom_col(fill='#222222') +
theme_minimal() +
labs(title='El sueño de los mamíferos',
subtitle='Media de horas de sueño por tipo de mamífero según alimentación',
caption='Proceedings of the National Academy of Sciences, 104 (3):1051-1056, 2007',
x='', y='') +
theme(legend.position='none',
text=element_text(family='Anton'),
plot.title=element_text(family='Anton', size=20),
plot.subtitle=element_text(family='Anton'),
axis.title.x = element_text(family='Anton', face='bold', hjust=1),
axis.title.y = element_text(family='Anton', face='bold', hjust=1),
strip.text=element_text(family='Anton', face='bold', size=14, hjust=0, color='white'),
strip.background=element_rect(fill='black'))
Como vemos, el eje x quedaría ordenado y la información queda mejor representada.
NOTA FINAL: Si nos fijamos, al principio hemos cambiado el valor desconocido, NA, por un valor concreto. El motivo del cambio es que ggplot representa los NA al final del gráfico siempre, sea cual sea la ordenación indicada. Esto puede interesarnos o no, dependiendo del caso. Para el ejemplo, consideramos más apropiado añadirlo como una categoría más, pero tengamos en cuenta que si ocurre, no hay que alarmarse!