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
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)
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(...))
@GavinSimpson: reorder
est une solution puissante et efficace pour cela:
ggplot(theTable,
aes(x=reorder(Position,Position,
function(x)-length(x)))) +
geom_bar()
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)
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()
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.
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')
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
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
.
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)
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.