2010-09-19 16 views
44

Ho un data.frame, che viene ordinato dal più alto al più basso. Per esempio:ggplot2: ordinamento di una trama

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

Ora, il dato è bello e ordinato, ma quando ho trama, esce allineati secondo fattore. È fastidioso, come lo risolvo?

+1

Con R versione 3.2.2, ottengo un errore: 'scale_y_continuous (" ", formatter =" percent "): argomento inutilizzato (formatter =" percent ")' – Iris

+0

Sì, credo che sia 'scale_y_continuos (etichette = percentuale) 'e devi anche caricare il pacchetto' scale '. –

+0

Quindi ho un nuovo errore 'Errore: stat_count() non deve essere usato con un aspetto estetico. – Iris

risposta

53

Qui ci sono un paio di modi.

La prima ordinerà cose in base all'ordine visto nel frame di dati:

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

Il secondo ordini i livelli basati su un'altra variabile (valore in questo caso):

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

Il secondo ha fornito il risultato che stavo cercando senza il "-". –

+0

riordino() verrà sovrascritto dal pacchetto gdata. Se non sai perché non funziona, questo potrebbe essere il motivo. –

+4

Vorrei che ggplot2 sarebbe stato riscritto per renderlo un po 'più semplice. Ho già ordinato i miei dati.frame e perché l'ordine non è rispettato dalla trama .... – userJT

2

Hai bisogno di fare la x-factor in un ordered fattore con l'ordinamento che si desidera, per esempio

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

Non conosco un modo migliore per fare l'operazione di ordinamento. Quello che ho lì funzionerà solo se non ci sono livelli duplicati per x$variable.

+0

Questo funziona per l'esempio che ho fornito, ma non sembra tradurre per il mio problema reale. –

+0

Ho modificato l'esempio per fornire dati reali con cui sto lavorando con –

+0

Funziona perfettamente quando lo provo ... – zwol

63

Questo sembra essere quello che stai cercando:

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

La funzione reorder() si riordina er gli elementi dell'asse x in base allo value di variable.

+6

Sarebbe bene aggiungere una spiegazione di cosa dovrebbe fare. – naught101

+0

Questo era esattamente quello che stavo cercando, grazie! – Timothy055

+2

Nel caso in cui qualcuno abbia problemi con l'argomento 'formatter =': questo è cambiato in 'labels = scale :: percent' nelle versioni più recenti (vedi http://stackoverflow.com/a/14511974/2761742). –

8

Recentemente ho avuto difficoltà con un problema correlato, discusso a lungo qui: Order of legend entries in ggplot2 barplots with coord_flip().

In questo caso, il motivo per cui ho avuto difficoltà a spiegare chiaramente il mio problema, ha coinvolto la relazione tra (l'ordine dei) fattori e coord_flip(), come sembra essere il caso qui.

ottengo il risultato desiderato aggiungendo + xlim(rev(levels(x$variable))) alla comunicazione ggplot:

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

Questo inverte l'ordine dei fattori come si trova nella cornice dati originali in asse x, che diventerà la y -axis con coord_flip(). Si noti che in questo particolare esempio, la variabile si trova anche in ordine alfabetico, ma la specifica di un ordine arbitrario di livelli all'interno di xlim() dovrebbe funzionare in generale.