r-faq title - Reihenfolge Bars in ggplot2 Balkendiagramm




barplot grouped (9)

Ich versuche, ein Balkendiagramm zu machen, bei dem der größte Balken der y-Achse am nächsten wäre und der kürzeste Balken am weitesten entfernt wäre. Das ist so ähnlich wie der Tisch, den ich habe

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

Also versuche ich ein Balkendiagramm zu erstellen, das die Anzahl der Spieler nach Position anzeigt

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

aber die Grafik zeigt den Torwart zuerst die Verteidigung und dann den Stürmer. Ich möchte, dass der Graph so angeordnet wird, dass der Verteidigungsbalken der y-Achse, der Torwart und schließlich der Stürmer am nächsten ist. Vielen Dank


Answers

Zusätzlich zu 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)             


Der Schlüssel bei der Bestellung besteht darin, die Ebenen des Faktors in der gewünschten Reihenfolge festzulegen. Ein geordneter Faktor ist nicht erforderlich. die zusätzliche Information in einem geordneten Faktor ist nicht notwendig und wenn diese Daten in irgendeinem statistischen Modell verwendet werden, kann die falsche Parametrisierung resultieren - Polynomkontraste sind für solche nominalen Daten 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 allgemeinsten Sinne müssen wir einfach die Faktorstufen in der gewünschten Reihenfolge einstellen. Es gibt mehrere Möglichkeiten, dies abhängig von der Situation zu tun. Zum Beispiel könnten wir tun:

levels(theTable$Position) <- c(...)

und liste einfach die Level in der gewünschten Reihenfolge auf der rechten Seite auf. Sie können auch die Reihenfolge der Ebenen innerhalb des Aufrufs zum Faktor wie oben angeben:

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

Eine einfache dplyr basierte Neuordnung von Faktoren 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

Wie reorder() in Alex Browns Antwort könnten wir auch forcats::fct_reorder() . Es wird im Grunde die Faktoren sortieren, die im 1. Argument angegeben sind, entsprechend den Werten im 2. Argument nach dem Anwenden einer spezifizierten Funktion (Standard = Median, was wir hier verwenden, da nur ein Wert pro Faktor-Ebene vorhanden ist).

Es ist eine Schande, dass in der Frage des OP die Reihenfolge, die erforderlich ist, auch alphabetisch ist, da dies die Standardsortierreihenfolge ist, wenn Sie Faktoren erstellen, und so verbergen, was diese Funktion tatsächlich tut. Um es klarer zu machen, ersetze ich "Torhüter" durch "Zoalkeeper".

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


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 Umordnen der Faktorstufen im Voraus, da die Zählung in dplyr nicht in ggplot oder in der table .


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

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

Sie müssen nur die Spalte " Position als einen geordneten Faktor angeben, in dem die Ebenen nach ihrer Anzahl angeordnet sind:

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

(Beachten Sie, dass die table(Position) eine Häufigkeitszählung der Spalte " table(Position) erzeugt.)

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


Ich denke, die bereits bereitgestellten Lösungen sind zu ausführlich. Eine prägnantere Möglichkeit, einen frequenzsortierten Barplot mit ggplot zu erstellen, ist

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

Es ist vergleichbar mit dem, was Alex Brown vorgeschlagen hat, aber ein bisschen kürzer und funktioniert ohne eine anonyme Funktionsdefinition.

Aktualisieren

Ich denke, meine alte Lösung war zu der Zeit gut, aber heutzutage würde ich eher forcats::fct_infreq die Faktorstufen nach Häufigkeit sortiert:

require(forcats)

ggplot(theTable, aes(fct_infreq(Position))) + geom_bar()

Sie können die Plotly R API verwenden , um dies zu formatieren . Unten finden Sie den Code dazu, und die Live-Version dieses Diagramms ist here .

# call Plotly and enter username and key
library(plotly)
p <- plotly(username="Username", key="API_KEY")

# enter data
x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x,1,1)

# format, listing y1 as your y.
First <- list(
x = x,
y = y1,
type = 'scatter',
mode = 'lines',
marker = list(
    color = 'rgb(0, 0, 255)',
    opacity = 0.5
 )
)

# format again, listing y2 as your y.
Second <- list(
x = x,
y = y2,
type = 'scatter',
mode = 'lines',
opacity = 0.8, 
marker = list(
    color = 'rgb(255, 0, 0)'
 )
)

# style background color
plot_bgcolor = 'rgb(245,245,247)'

# and structure the response. Plotly returns a URL when you make the call. 
response<-p$plotly(list(First,Second), kwargs = list(layout=layout))

Volle Enthüllung: Ich bin im Plotly-Team.





r ggplot2 r-faq