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
J'essaie donc de construire un graphique à barres qui montrerait le nombre de joueurs en fonction de la position
p <- ggplot(theTable, aes(x = Position)) + geom_bar(binwidth = 1)
mais le graphique montre le gardien de but barré d’abord à la défense puis à l’attaquant. Je voudrais que le graphique soit ordonné de manière à ce que la barre de défense soit la plus proche de l’axe des y, celle du gardien de but et enfin celle de l’attaquant . Merci
La clé de la commande consiste à définir les niveaux du facteur dans l'ordre de votre choix. 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, un paramétrage incorrect peut en résulter - les contrastes polynomiaux ne conviennent pas à des données nominales telles que 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 devons simplement définir les niveaux de facteurs dans l'ordre souhaité. Si non précisé, les niveaux d'un facteur seront triés par ordre alphabétique. Vous pouvez également spécifier l'ordre des niveaux dans l'appel à factoriser comme ci-dessus, et d'autres méthodes sont également possibles.
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()
Utilisez 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 trié en fréquence avec ggplot est
ggplot(theTable, aes(x=reorder(Position, -table(Position)[Position]))) + geom_bar()
Cela ressemble à ce que Alex Brown a suggéré, mais un peu plus court et fonctionne sans aucune définition de fonction.
Mettre à jour
Je pense que mon ancienne solution était bonne à l'époque, mais aujourd'hui, je préfère utiliser forcats::fct_infreq
, qui consiste à trier les niveaux de facteurs par fréquence:
require(forcats)
ggplot(theTable, aes(fct_infreq(Position))) + geom_bar()
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 argument, en fonction des valeurs du second argument après l'application d'une fonction spécifiée (par défaut = médiane, ce que nous utilisons ici comme n'ayant qu'une valeur par niveau de facteur).
Il est dommage que, dans la question du PO, l'ordre requis soit également alphabétique, puisqu'il s'agit de l'ordre de tri par défaut lorsque vous créez des facteurs, ce qui masquera donc le rôle réel de cette fonction. Pour que ce soit plus clair, je remplacerai "Gardien de but" par "Gardien de Zoal".
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
Il vous suffit de spécifier que la colonne Position
est un facteur ordonné où les niveaux sont classés en fonction de leur nombre:
theTable <- transform( theTable,
Position = ordered(Position, levels = names( sort(-table(Position)))))
(Notez que table(Position)
produit un compte de fréquence de la colonne Position
.)
Ensuite, votre fonction ggplot
affichera les barres dans l'ordre décroissant de comptage . Je ne sais pas s'il existe une option dans geom_bar
pour le faire sans avoir à créer explicitement un facteur ordonné.
En plus de forcats :: fct_infreq, mentionné par @ HolgerBrandl, il existe 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)
Je suis d’accord avec Zach pour dire 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")
Cela sera également beaucoup plus rapide que de réorganiser les niveaux de facteurs au préalable, car le comptage est effectué dans dplyr et non dans ggplot ou à l'aide de table
.
Si les colonnes du graphique 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 du tri (croissant/décroissant).
Voici quelques données à tester:
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.
Puisque nous ne regardons que la distribution d'une variable unique ("Position") par opposition à la relation entre deux variables, alors peut-être un histogramme le graphique le plus approprié. ggplot a geom_histogram () cela facilite les choses:
ggplot(theTable, aes(x = Position)) + geom_histogram(stat="count")
Utilisation de geom_histogram ():
Je pense que geom_histogram ( ) est un peu bizarre car il traite les données continues et discrètes différemment.
Pour données continues, vous pouvez simplement utiliser geom_histogram () sans paramètre . Par exemple, si nous ajoutons un vecteur numérique "Score" ...
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
et utilisez geom_histogram () sur la variable "Score" ...
ggplot(theTable, aes(x = Score)) + geom_histogram()
Pour données discrètes comme "Position", nous devons spécifier une statistique calculée calculée par l'esthétique pour donner la valeur y à la hauteur des barres à l'aide de stat = "count"
:
ggplot(theTable, aes(x = Position)) + geom_histogram(stat = "count")
Remarque: Curieusement et déroutant, vous pouvez également utiliser stat = "count"
pour des données continues, ce qui fournit un graphique plus esthétique.
ggplot(theTable, aes(x = Score)) + geom_histogram(stat = "count")
Edits: Réponse étendue en réponse aux suggestions utiles de DebanjanB .
Une autre alternative utilisant reorder pour ordonner les niveaux d’un facteur. En ordre croissant (n) ou en ordre décroissant (-n) en fonction du nombre. Très similaire à celui utilisant fct_reorder
du paquet forcats
:
Ordre décroissant
df %>%
count(Position) %>%
ggplot(aes(x = reorder(Position, -n), y = n)) +
geom_bar(stat = 'identity') +
xlab("Position")
Ordre croissant
df %>%
count(Position) %>%
ggplot(aes(x = reorder(Position, n), y = n)) +
geom_bar(stat = 'identity') +
xlab("Position")
Trame de données:
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))