2010-07-15 13 views
84

Ich mache ein ausgewichenes Balkendiagramm mit ggplot mit diskreten X-Skala, die X-Achse sind jetzt in alphabetischer Reihenfolge angeordnet, aber ich muss es neu anordnen, so dass es nach dem Wert sortiert ist die y-Achse (dh der höchste Balken wird auf der linken Seite positioniert).Ändern Sie die Reihenfolge einer diskreten x-Skala

Ich versuchte Ordnung oder Sortierung, aber sortiere die X-Achse, aber nicht die Balken respektive.

Was habe ich falsch gemacht?

Antwort

77

Versuchen Sie manuell, die Ebenen des Faktors auf der x-Achse einzustellen. Zum Beispiel:

library(ggplot2) 
# Automatic levels 
ggplot(mtcars, aes(factor(cyl))) + geom_bar()  

ggplot of the cars dataset with factor levels automatically determined

# Manual levels 
cyl_table <- table(mtcars$cyl) 
cyl_levels <- names(cyl_table)[order(cyl_table)] 
mtcars$cyl2 <- factor(mtcars$cyl, levels = cyl_levels) 
# Just to be clear, the above line is no different than: 
# mtcars$cyl2 <- factor(mtcars$cyl, levels = c("6","4","8")) 
# You can manually set the levels in whatever order you please. 
ggplot(mtcars, aes(cyl2)) + geom_bar() 

ggplot of the cars dataset with factor levels reordered manually

Wie James in seiner Antwort darauf hingewiesen, ist reorder der idiomatische Weg Faktorstufen von Nachbestellung.

mtcars$cyl3 <- with(mtcars, reorder(cyl, cyl, function(x) -length(x))) 
ggplot(mtcars, aes(cyl3)) + geom_bar() 

ggplot of the cars dataset with factor levels reordered using the reorder function

25

können Sie reorder verwenden:

qplot(reorder(factor(cyl),factor(cyl),length),data=mtcars,geom="bar") 

Edit:

Um die höchste Bar auf der linken Seite zu haben, müssen Sie ein bisschen eine Flickschusterei verwenden :

qplot(reorder(factor(cyl),factor(cyl),function(x) length(x)*-1), 
    data=mtcars,geom="bar") 

Ich würde erwarten, dass dies auch negative Höhen haben, aber es tut nicht, so funktioniert es!

+5

Ich bin schockiert diese Antwort nicht mehr upvotes hat, 90% der Zeit ist dies der richtige Weg, es zu tun. – Gregor

+0

Ich denke, beide Faktor-Aufrufe sind überflüssig. Es gibt einen impliziten Aufruf für das erste Argument und das zweite Argument wird als numerisch angenommen. –

134

Der beste Weg für mich war, Vektor mit Kategorien zu verwenden, die ich als limits Parameter zu scale_x_discrete benötigen. Ich denke, es ist eine ziemlich einfache und unkomplizierte Lösung.

ggplot(mtcars, aes(factor(cyl))) + 
geom_bar() + 
scale_x_discrete(limits=c(8,4,6)) 

enter image description here

+1

Dies "funktioniert" .... aber die Legende zeigt immer noch die verwirrten Bestellungen ... –

+0

@HendyIrawan gibt es keine Legende, es sei denn, Sie haben andere Dimensionen (Farbe, Füllung) auch auf die gleiche Variable abgebildet. – Gregor

2

Ich weiß, das ist alt, aber vielleicht diese Funktion habe ich ist es an jemanden nützlich:

order_axis<-function(data, axis, column) 
{ 
    # for interactivity with ggplot2 
    arguments <- as.list(match.call()) 
    col <- eval(arguments$column, data) 
    ax <- eval(arguments$axis, data) 

    # evaluated factors 
    a<-reorder(with(data, ax), 
      with(data, col)) 

    #new_data 
    df<-cbind.data.frame(data) 
    # define new var 
    within(df, 
     do.call("<-",list(paste0(as.character(arguments$axis),"_o"), a))) 
} 

Jetzt, mit dieser Funktion können Sie interaktiv mit ggplot2 zeichnen können, wie folgt:

ggplot(order_axis(df, AXIS_X, COLUMN_Y), 
     aes(x = AXIS_X_o, y = COLUMN_Y)) + 
     geom_bar(stat = "identity") 

Wie zu sehen ist, dieDie-Funktion erstellt ein anderes Datenframe mit einer neuen Spalte, die gleich benannt ist, aber am Ende mit _o. Diese neue Spalte hat Ebenen in aufsteigender Reihenfolge, so dass ggplot2 automatisch in dieser Reihenfolge plottet.

Dies ist etwas begrenzt (funktioniert nur für Zeichen oder Faktor und numerische Kombinationen von Spalten und in aufsteigender Reihenfolge), aber ich finde es immer noch sehr nützlich für das Plotten von unterwegs.

13

Hadley entwickelt ein Paket namens forcats. Dieses Paket macht die Aufgabe so viel einfacher.Sie können fct_infreq() ausnutzen, wenn Sie die Reihenfolge der x-Achse um die Häufigkeit eines Faktors ändern möchten. Im Fall des Beispiels mtcars in diesem Post möchten Sie die Ebenen cyl mit der Häufigkeit jedes Levels neu anordnen. Die Ebene, die am häufigsten angezeigt wird, bleibt auf der linken Seite. Alles, was Sie brauchen, ist die fct_infreq().

library(ggplot2) 
library(forcats) 

ggplot(mtcars, aes(fct_infreq(factor(cyl)))) + 
geom_bar() + 
labs(x = "cyl") 

Wenn Sie in die andere Richtung gehen wollen um, können Sie fct_rev() zusammen mit fct_infreq() verwenden.

ggplot(mtcars, aes(fct_rev(fct_infreq(factor(cyl))))) + 
geom_bar() + 
labs(x = "cyl") 

enter image description here

Verwandte Themen