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
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)
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(...))
@GavinSimpson: reorder
ist eine leistungsstarke und effektive Lösung dafür:
ggplot(theTable,
aes(x=reorder(Position,Position,
function(x)-length(x)))) +
geom_bar()
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)
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()
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')
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
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.
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)
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
.
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.
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")
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()
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")
Edits: Erweiterte Antwort auf die hilfreichen Vorschläge von DebanjanB .
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")
In aufsteigender Reihenfolge
df %>%
count(Position) %>%
ggplot(aes(x = reorder(Position, n), y = n)) +
geom_bar(stat = 'identity') +
xlab("Position")
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))