En ocasiones uno quiere ordenar las etiquetas de variables categóricas que aparecen en el eje x de una gráfica hecha en ggplot2. Para ello lo que hay que ordenar son los niveles (levels) de la variable en cuestión.

 

library(ggplot2)
#Generamos unos datos aleatorios
muestra <- sample(c("Muy Bueno", "Bueno", "Regular", "Malo", "Muy malo"), 100, replace=TRUE)

#Consultamos el orden de frecuencia de la muestra. En este caso de mayor a menor.
#Guardamos el orden de los levels en una variable
orden <- names(sort(table(muestra), decreasing=TRUE))

#Convertimos en un factor con los niveles ordenados
#y en un data.frame para que ggplot lo reconozca
muestra <- data.frame(valoracion=factor(muestra, levels=orden))

#Generamos e imprimimos la gráfica
print(ggplot(muestra, aes(x=valoracion, y=..count..)) + geom_bar(binwidth=1))

Éste es el resultado.

Gráfica con etiquetas ordenadas por frecuencia

Puede ser que el gráfico aparezca diferente al que muestro aquí, ya que se basa en una muestra de resultados aleatorios.

 

Edito el 06/06/2014:

Acabo de encontrar una función que permite ordenar los niveles de un factor a partir de otra variable. Esto puede ser útil, ya que ggplot2 utiliza los niveles para ordenar los elementos en la gráfica. Se trata de la función reorder, del paquete stats, que habrá que cargar antes de utilizarla con library(stats)).

La función toma 2 parámetros, primeramente el factor que se quiere ordenar y en segundo lugar un valor numérico por el que se quiere ordenar. En el caso de que queramos ordenar de forma inversa le podemos añadir un signo negativo al valor numérico.

Aquí va el ejemplo con la gráfica de arriba.

library(stats)
library(ggplot2)

#Generamos unos datos aleatorios para el ejemplo
muestra <- sample(c("Muy Bueno", "Bueno", "Regular", "Malo", "Muy malo"), 100, replace=TRUE)

#Creamos un data.frame con las frecuencias de la muestra
muestra <- ddply(as.data.frame(muestra), .(muestra), nrow)

#Ordenamos los datos por la variable V1. En este caso para que sea decreciente, le he puesto un signo negativo
#a V1.
muestra$muestra <- with(muestra, reorder(muestra, -V1))

#Genero el gráfico a partir de los datos
p <- ggplot(muestra, aes(x=muestra, y=V1)) + geom_bar(stat="identity") print(p)

 

La figura será la misma que he mostrado arriba.

Comentarios   

#1 Carlos 05-04-2017 14:30
Hola Franz:

Estoy intentando hacer algo con ggplot, pero no lo consigo.

Tengo una gráfica que pinto con dos geom_line. Uno de ellos dibuja una línea diaria, y el otro, semanal.
Hasta ahí bien, controlo las etiquetas del eje x con scale_x_date, indicando que me ponga marcas cada dos semanas, y marco los límites que quiero del eje.

Mi problema llega cuando quiero hacerlo más bonito y sacar una agrupación debajo indicando el año.

Lo más que me he acercado ha sido usando un facet_wrap, con scales="free_x" , pero eso hace que se me corten las líneas en el cambio de año, y, además, como tengo menos datos en 2017 que en 2016, el escalado del eje me lo descuadra, haciendo una separación entre puntos más grande que otra.

¿Sabrías tú cómo solucionarlo? Hasta ahora todo lo que he visto por ahí era hardcodeando la posición de un annotation, cosa que no puedo aplicar, ya que los datos del gráfico son cambiantes, y mis coordenadas de dicho annotation variarían.

Un saludo y muchas gracias.

No tiene permiso suficiente para añadir comentarios