2010-09-19 16 views
44

Tengo un data.frame, que se ordena de mayor a menor. Por ejemplo:ggplot2: ordenando un diagrama

x <- structure(list(variable = structure(c(10L, 6L, 3L, 4L, 2L, 8L, 
9L, 5L, 1L, 7L), .Label = c("a", "b", "c", "d", "e", "f", "g", 
"h", "i", "j"), class = c("ordered", "factor")), value = c(0.990683229813665, 
0.975155279503106, 0.928571428571429, 0.807453416149068, 0.717391304347826, 
0.388198757763975, 0.357142857142857, 0.201863354037267, 0.173913043478261, 
0.0496894409937888)), .Names = c("variable", "value"), row.names = c(10L, 
6L, 3L, 4L, 2L, 8L, 9L, 5L, 1L, 7L), class = "data.frame") 

ggplot(x, aes(x=variable,y=value)) + geom_bar() + 
scale_y_continuous("",formatter="percent") + coord_flip() 

Ahora, los datos es agradable y ordenado, pero cuando la trama, que salga ordenadas por el factor. Es molesto, ¿cómo lo arreglo?

+1

Con R versión 3.2.2, aparece un error: 'scale_y_continuous (" ", formatter =" percent "): argumento no utilizado (formatter =" percent ")' – Iris

+0

Sí, creo que es 'scale_y_continuos (labels = percent) 'y también debe cargar el paquete' scales'. –

+0

Luego tengo un nuevo error 'Error: stat_count() no debe usarse con una estética y. – Iris

Respuesta

53

Aquí hay un par de maneras.

La primera ordenará cosas basado en el orden visto en la trama de datos:

x$variable <- factor(x$variable, levels=unique(as.character(x$variable))) 

El segundo ordena a los niveles basados ​​en otra variable (valor en este caso):

x <- transform(x, variable=reorder(variable, -value)) 
+1

El segundo proporcionó el resultado que estaba buscando sin el "-". –

+0

reordenar() será sobrescrito por el paquete gdata. Si no sabes por qué no funciona, esta podría ser la razón. –

+4

Ojalá se reescriba ggplot2 para hacerlo un poco más fácil. Ya ordeno mis datos.marco y por qué el orden no es respetado por la trama .... – userJT

2

Usted necesita hacer el factor X en un factor ordered con el orden que desee, por ejemplo

x <- data.frame("variable"=letters[1:5], "value"=rnorm(5)) ## example data 
x <- x[with(x,order(-value)), ] ## Sorting 
x$variable <- ordered(x$variable, levels=levels(x$variable)[unclass(x$variable)]) 

ggplot(x, aes(x=variable,y=value)) + geom_bar() + 
    scale_y_continuous("",formatter="percent") + coord_flip() 

No sé ninguna forma mejor de hacer la operación de ordenación. Lo que tengo allí solo funcionará si no hay niveles duplicados para x$variable.

+0

Esto funciona para el ejemplo que he proporcionado, pero no parece traducirse por mi problema real. –

+0

He cambiado el ejemplo para proporcionar los datos reales con los que estoy trabajando –

+0

Funciona perfectamente cuando lo intento ... – zwol

63

Este parece ser lo que estás buscando:

g <- ggplot(x, aes(reorder(variable, value), value)) 
g + geom_bar() + scale_y_continuous(formatter="percent") + coord_flip() 

La función reorder() se REORD er sus artículos del eje x según value de variable.

+6

Sería bueno agregar una explicación de lo que se supone que debe hacer. – naught101

+0

Esto era exactamente lo que estaba buscando, ¡gracias! – Timothy055

+2

En caso de que alguien tenga problemas con el argumento 'formatter =': esto ha cambiado a 'labels = scales :: percent' en versiones más recientes (ver http://stackoverflow.com/a/14511974/2761742). –

8

Recientemente he estado luchando con un problema relacionado, discutido extensamente aquí: Order of legend entries in ggplot2 barplots with coord_flip().

Da la casualidad de que la razón por la que tuve dificultades para explicar mi problema, involucraba la relación entre (el orden de) factores y coord_flip(), como parece ser el caso aquí.

I obtener el resultado deseado mediante la adición de + xlim(rev(levels(x$variable))) a la declaración ggplot:

ggplot(x, aes(x=variable,y=value)) + geom_bar() + 
scale_y_continuous("",formatter="percent") + coord_flip() 
+ xlim(rev(levels(x$variable))) 

Esto invierte el orden de los factores como se encuentran en la trama de datos original de en el eje x, que se convertirán en la Y eje con coord_flip(). Observe que en este ejemplo particular, la variable también está en orden alfabético, pero especificar un orden arbitrario de niveles dentro de xlim() debería funcionar en general.

Cuestiones relacionadas