Barres d'ordres dans le graphe à barres ggplot2

j'essaie de faire un graphique à barres où la barre la plus grande serait la plus proche de l'axe des y et la barre la plus courte serait la plus éloignée. Donc c'est un peu comme la Table que j'ai

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

donc j'essaie de construire un graphique à barres qui montrerait le nombre de joueurs selon la position

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

mais le graphique montre la barre du gardien d'abord puis la défense, et enfin le buteur. Je voudrais que le graphique soit ordonné de sorte que la barre de défense est la plus proche de l'axe y, celle du gardien de but, et enfin celle du buteur. Merci

228
demandé sur Roland Ewald 2011-03-06 07:20:48

10 réponses

la clé avec l'ordre est de définir les niveaux du facteur dans l'ordre que vous voulez. Un facteur ordonné n'est pas nécessaire; l'information supplémentaire dans un facteur ordonné n'est pas nécessaire et si ces données sont utilisées dans n'importe quel modèle statistique, la paramétrisation erronée pourrait en résulter - les contrastes polynomiaux ne sont pas appropriés pour des données nominales comme celle-ci.

## 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

Dans le sens le plus général, nous avons simplement besoin de définir les niveaux de facteur doivent être dans l'ordre désiré. Si spécifié, les niveaux d'un facteur sont triés par ordre alphabétique. Cependant, il y a plusieurs façons de changer l'ordre en une séquence précise selon la situation. Par exemple, nous pourrions faire:

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

et de simplement énumérer les niveaux dans l'ordre souhaité sur le côté droit. Vous pouvez également spécifier l'ordre de niveau dans l'appel à factor comme ci-dessus:

theTable$Position <- factor(theTable$Position, levels = c(...))
171
répondu Gavin Simpson 2018-06-27 18:48:48

@GavinSimpson: reorder est une solution puissante et efficace pour cela:

ggplot(theTable,
       aes(x=reorder(Position,Position,
                     function(x)-length(x)))) +
       geom_bar()
177
répondu Alex Brown 2014-03-05 19:50:11

utilisant scale_x_discrete (limits = ...) pour spécifier l'ordre des barres.

positions <- c("Goalkeeper", "Defense", "Striker")
p <- ggplot(theTable, aes(x = Position)) + scale_x_discrete(limits = positions)
112
répondu QIBIN LI 2015-07-02 16:35:27

je pense que les solutions déjà fournies sont trop verbeuses. Une façon plus concise de faire un barplot de fréquence trié avec ggplot est

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

c'est similaire à ce Qu'Alex Brown a suggéré, mais un peu plus court et fonctionne sans une définition de fonction quelconque.

mise à Jour

je pense que mon ancienne solution était bonne à l'époque, mais de nos jours je préfère utiliser forcats::fct_infreq qui est facteur de tri niveaux par fréquence:

require(forcats)

ggplot(theTable, aes(fct_infreq(Position))) + geom_bar()
68
répondu Holger Brandl 2017-01-11 14:58:56

vous avez juste besoin de préciser que la colonne Position est un facteur ordonné où les niveaux sont ordonnés par leurs comptes:

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

(notez que le table(Position) produit un comptage de fréquence de la colonne Position .)

alors votre fonction ggplot affichera les barres dans l'ordre décroissant du nombre. Je ne sais pas s'il y a une option dans geom_bar pour le faire sans avoir à créer explicitement un commandé facteur.

16
répondu Prasad Chalasani 2011-03-06 14:53:46

comme reorder() dans la réponse D'Alex Brown, nous pourrions aussi utiliser forcats::fct_reorder() . Il va essentiellement trier les facteurs spécifiés dans le 1er arg, en fonction des valeurs dans le 2e arg après l'application d'une fonction spécifiée (par défaut = médiane, qui est ce que nous utilisons ici que juste une valeur par niveau de facteur).

c'est une honte que dans la question de L'OP, l'ordre requis est aussi alphabétique car c'est l'ordre de tri par défaut quand vous créez des facteurs, alors va cacher ce que cette fonction est en train de faire. Pour être plus clair, je vais remplacer "gardien de but" par "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')

enter image description here

16
répondu user2739472 2016-12-08 13:35:47

une simple réorganisation des facteurs basée sur dplyr peut résoudre ce problème:

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
15
répondu zach 2016-10-04 14:32:17

je suis d'accord avec zach que Compter dans dplyr est la meilleure solution. J'ai trouvé que c'était la version la plus courte:

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

ce sera également beaucoup plus rapide que la réorganisation des niveaux de facteur à l'avance puisque le compte est fait en dplyr pas en ggplot ou en utilisant table .

9
répondu Alexandru Papiu 2016-10-04 16:29:43

en plus des forcats:: fct_infreq, mentionné par @Holgebrandl, il y a forcats::fct_rev, qui inverse l'ordre des facteurs.

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

9
répondu Robert McDonald 2018-02-25 20:19:04

si les colonnes du diagramme proviennent d'une variable numérique comme dans le cadre de données ci-dessous, vous pouvez utiliser une solution plus simple:

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

le signe moins avant la variable de tri (- Qty) contrôle le sens de Tri (ascendant / descendant)

voici quelques données pour les tests:

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

Quand j'ai trouvé ce fil, c'était la réponse que je cherchais. J'espère que c'est utile pour les autres.

3
répondu JColares 2018-08-03 07:17:19