wake-up-neo.com

Balken im ggplot2-Balkendiagramm bestellen

Ich versuche, ein Balkendiagramm zu erstellen, bei dem der größte Balken der y-Achse am nächsten ist und der kürzeste Balken am weitesten entfernt ist. Das ist also eine Art Tabelle, die ich habe

    Name   Position
1   James  Goalkeeper
2   Frank  Goalkeeper
3   Jean   Defense
4   Steve  Defense
5   John   Defense
6   Tim    Striker

Ich versuche also, ein Balkendiagramm zu erstellen, das die Anzahl der Spieler nach Position anzeigt

p <- ggplot(theTable, aes(x = Position)) + geom_bar(binwidth = 1)

die Grafik zeigt jedoch zunächst den Torwartbalken, dann die Abwehr und schließlich den Stürmer. Ich möchte, dass der Graph so angeordnet wird, dass der Verteidigungsbalken der y-Achse am nächsten ist, der Torwart eine und schließlich der Stürmer

247
Julio Diaz

Der Schlüssel bei der Bestellung besteht darin, die Stufen des Faktors in der von Ihnen gewünschten Reihenfolge einzustellen. Ein geordneter Faktor ist nicht erforderlich. Die zusätzlichen Informationen in einem geordneten Faktor sind nicht erforderlich. Wenn diese Daten in einem statistischen Modell verwendet werden, kann dies zu einer falschen Parametrisierung führen. Polynomkontraste sind für solche Nominaldaten nicht richtig.

## set the levels in order we want
theTable <- within(theTable, 
                   Position <- factor(Position, 
                                      levels=names(sort(table(Position), 
                                                        decreasing=TRUE))))
## plot
ggplot(theTable,aes(x=Position))+geom_bar(binwidth=1)

barplot figure

Im allgemeinen Sinne müssen wir die Faktorstufen einfach in der gewünschten Reihenfolge einstellen. Wenn keine Angabe erfolgt, werden die Stufen eines Faktors alphabetisch sortiert. Sie können auch die Stufenreihenfolge innerhalb des Aufrufs-Faktors wie oben angeben. Andere Möglichkeiten sind ebenfalls möglich.

theTable$Position <- factor(theTable$Position, levels = c(...))
182
Gavin Simpson

@GavinSimpson: reorder ist eine leistungsstarke und effektive Lösung dafür:

ggplot(theTable,
       aes(x=reorder(Position,Position,
                     function(x)-length(x)))) +
       geom_bar()
190
Alex Brown

Verwenden Sie scale_x_discrete (limits = ...), um die Reihenfolge der Balken festzulegen.

positions <- c("Goalkeeper", "Defense", "Striker")
p <- ggplot(theTable, aes(x = Position)) + scale_x_discrete(limits = positions)
122
QIBIN LI

Ich denke, die bereits zur Verfügung gestellten Lösungen sind zu ausführlich. Eine prägnantere Methode, um einen frequenzsortierten Barplot mit ggplot zu erstellen, ist

ggplot(theTable, aes(x=reorder(Position, -table(Position)[Position]))) + geom_bar()

Es ist dem, was Alex Brown vorschlug, ähnlich, aber etwas kürzer und funktioniert ohne jegliche Funktionsdefinition.

Update

Ich denke, meine alte Lösung war zu der Zeit gut, aber heutzutage benutze ich lieber forcats::fct_infreq, was die Faktorstufen nach Häufigkeit sortiert:

require(forcats)

ggplot(theTable, aes(fct_infreq(Position))) + geom_bar()
72
Holger Brandl

Wie reorder() in Alex Browns Antwort könnten wir auch forcats::fct_reorder() verwenden. Grundsätzlich werden die im ersten Argument angegebenen Faktoren nach den Werten im 2. Argument nach Anwendung einer angegebenen Funktion sortiert (Standard = Median, was wir hier verwenden, da nur ein Wert pro Faktorebene verwendet wird).

Es ist eine Schande, dass in der Frage des OPs die erforderliche Reihenfolge auch alphabetisch ist, da dies die Standard-Sortierreihenfolge ist, wenn Sie Faktoren erstellen. Dadurch wird verborgen, was diese Funktion tatsächlich tut. Um es klarer zu machen, werde ich "Torwart" durch "Zoalkeeper" ersetzen.

library(tidyverse)
library(forcats)

theTable <- data.frame(
                Name = c('James', 'Frank', 'Jean', 'Steve', 'John', 'Tim'),
                Position = c('Zoalkeeper', 'Zoalkeeper', 'Defense',
                             'Defense', 'Defense', 'Striker'))

theTable %>%
    count(Position) %>%
    mutate(Position = fct_reorder(Position, n, .desc = TRUE)) %>%
    ggplot(aes(x = Position, y = n)) + geom_bar(stat = 'identity')

 enter image description here

20
user2739472

Eine einfache Umstellung der Faktoren auf Dplyr-Basis kann dieses Problem lösen:

library(dplyr)

#reorder the table and reset the factor to that ordering
theTable %>%
  group_by(Position) %>%                              # calculate the counts
  summarize(counts = n()) %>%
  arrange(-counts) %>%                                # sort by counts
  mutate(Position = factor(Position, Position)) %>%   # reset factor
  ggplot(aes(x=Position, y=counts)) +                 # plot 
    geom_bar(stat="identity")                         # plot histogram
18
zach

Sie müssen lediglich die Position-Spalte als geordneten Faktor angeben wobei die Ebenen nach ihren Zählungen geordnet sind:

theTable <- transform( theTable,
       Position = ordered(Position, levels = names( sort(-table(Position)))))

(Beachten Sie, dass die table(Position) eine Frequenzzählung der Position-Spalte erzeugt.)

Dann zeigt Ihre ggplot-Funktion die Balken in absteigender Reihenfolge der Anzahl . Ich weiß nicht, ob es in geom_bar eine Option gibt, dies zu tun, ohne explizit einen geordneten Faktor erstellen zu müssen.

16

Neben forcats :: fct_infreq, das von @ HolgerBrandl erwähnt wird, gibt es forcats :: fct_rev, das die Reihenfolge der Faktoren umkehrt.

theTable <- data.frame(
    Position= 
        c("Zoalkeeper", "Zoalkeeper", "Defense",
          "Defense", "Defense", "Striker"),
    Name=c("James", "Frank","Jean",
           "Steve","John", "Tim"))

p1 <- ggplot(theTable, aes(x = Position)) + geom_bar()
p2 <- ggplot(theTable, aes(x = fct_infreq(Position))) + geom_bar()
p3 <- ggplot(theTable, aes(x = fct_rev(fct_infreq(Position)))) + geom_bar()

gridExtra::grid.arrange(p1, p2, p3, nrow=3)             

 gplot output

11
Robert McDonald

Ich stimme mit zach überein, dass das Zählen innerhalb von Dplyr die beste Lösung ist. Ich habe festgestellt, dass dies die kürzeste Version ist:

dplyr::count(theTable, Position) %>%
          arrange(-n) %>%
          mutate(Position = factor(Position, Position)) %>%
          ggplot(aes(x=Position, y=n)) + geom_bar(stat="identity")

Dies ist auch wesentlich schneller als das vorherige Umordnen der Faktorstufen, da die Zählung in dplyr erfolgt und nicht in ggplot oder mit table.

9
Alexandru Papiu

Wenn die Diagrammspalten wie im untenstehenden Datenrahmen aus einer numerischen Variablen stammen, können Sie eine einfachere Lösung verwenden:

ggplot(df, aes(x = reorder(Colors, -Qty, sum), y = Qty)) 
+ geom_bar(stat = "identity")  

Das Minuszeichen vor der Sortiervariablen (-Qty) steuert die Sortierrichtung (aufsteigend/absteigend)

Hier einige Daten zum Testen:

df <- data.frame(Colors = c("Green","Yellow","Blue","Red","Yellow","Blue"),  
                 Qty = c(7,4,5,1,3,6)
                )

**Sample data:**
  Colors Qty
1  Green   7
2 Yellow   4
3   Blue   5
4    Red   1
5 Yellow   3
6   Blue   6

Als ich diesen Thread fand, war das die Antwort, nach der ich gesucht hatte. Hoffe, es ist nützlich für andere.

7
JColares

Da wir nur die Verteilung einer Einzelvariablen ("Position") betrachten, anstatt die Beziehung zwischen zwei Variablen zu betrachten, wäre ein Histogramm vielleicht der passendere Graph. ggplot hat geom_histogram () das macht es einfach:

ggplot(theTable, aes(x = Position)) + geom_histogram(stat="count")

 enter image description here

Geom_histogram () verwenden:

Ich denke, dass geom_histogram ( ) etwas skurril ist, da es kontinuierliche und diskrete Daten unterschiedlich behandelt. 

Für stetige Daten können Sie einfach geom_histogram () ohne Parameter ..__ verwenden. Wenn Sie zum Beispiel einen numerischen Vektor "Score" hinzufügen, ...

    Name   Position   Score  
1   James  Goalkeeper 10
2   Frank  Goalkeeper 20
3   Jean   Defense    10
4   Steve  Defense    10
5   John   Defense    20
6   Tim    Striker    50

und benutze geom_histogram () für die Variable "Score" ...

ggplot(theTable, aes(x = Score)) + geom_histogram()

 enter image description here

Für diskrete Daten wie "Position" müssen wir eine berechnete Statistik angeben, die von der Ästhetik berechnet wird, um den y-Wert für die Höhe der Balken mit stat = "count" anzugeben:

 ggplot(theTable, aes(x = Position)) + geom_histogram(stat = "count")

Anmerkung: Neugierig und verwirrend können Sie stat = "count" auch für fortlaufende Daten verwenden, und ich denke, es liefert einen ästhetisch ansprechenden Graphen.

ggplot(theTable, aes(x = Score)) + geom_histogram(stat = "count")

 enter image description here

Edits: Erweiterte Antwort auf die hilfreichen Vorschläge von DebanjanB .

1
indubitably

Eine andere Alternative mit reorder, um die Stufen eines Faktors zu ordnen. In aufsteigender (n) oder absteigender Reihenfolge (-n) basierend auf der Anzahl. Sehr ähnlich dem, der fct_reorder aus dem forcats-Paket verwendet:

Absteigende Reihenfolge

df %>%
  count(Position) %>%
  ggplot(aes(x = reorder(Position, -n), y = n)) +
  geom_bar(stat = 'identity') +
  xlab("Position")

 enter image description here

In aufsteigender Reihenfolge

df %>%
  count(Position) %>%
  ggplot(aes(x = reorder(Position, n), y = n)) +
  geom_bar(stat = 'identity') +
  xlab("Position")

 enter image description here

Datenrahmen:

df <- structure(list(Position = structure(c(3L, 3L, 1L, 1L, 1L, 2L), .Label = c("Defense", 
"Striker", "Zoalkeeper"), class = "factor"), Name = structure(c(2L, 
1L, 3L, 5L, 4L, 6L), .Label = c("Frank", "James", "Jean", "John", 
"Steve", "Tim"), class = "factor")), class = "data.frame", row.names = c(NA, 
-6L))
0
mpalanco