Je trace une variable catégorielle et au lieu d’afficher les comptes pour chaque valeur de catégorie.
Je cherche un moyen d'obtenir ggplot
pour afficher le pourcentage de valeurs de cette catégorie. Bien sûr, il est possible de créer une autre variable avec le pourcentage calculé et de tracer celle-ci, mais je dois le faire plusieurs fois et j'espère y parvenir en une seule commande.
Je faisais des expériences avec quelque chose comme
qplot(mydataf) +
stat_bin(aes(n = nrow(mydataf), y = ..count../n)) +
scale_y_continuous(formatter = "percent")
mais je dois l'utiliser de manière incorrecte, car j'ai des erreurs.
Pour reproduire facilement la configuration, voici un exemple simplifié:
mydata <- c ("aa", "bb", NULL, "bb", "cc", "aa", "aa", "aa", "ee", NULL, "cc");
mydataf <- factor(mydata);
qplot (mydataf); #this shows the count, I'm looking to see % displayed.
Dans le cas réel, j'utiliserai probablement ggplot
au lieu de qplot
, mais la bonne façon d'utiliser stat_bin m'échappe toujours.
J'ai aussi essayé ces quatre approches:
ggplot(mydataf, aes(y = (..count..)/sum(..count..))) +
scale_y_continuous(formatter = 'percent');
ggplot(mydataf, aes(y = (..count..)/sum(..count..))) +
scale_y_continuous(formatter = 'percent') + geom_bar();
ggplot(mydataf, aes(x = levels(mydataf), y = (..count..)/sum(..count..))) +
scale_y_continuous(formatter = 'percent');
ggplot(mydataf, aes(x = levels(mydataf), y = (..count..)/sum(..count..))) +
scale_y_continuous(formatter = 'percent') + geom_bar();
mais tous les 4 donnent:
Error: ggplot2 doesn't know how to deal with data of class factor
La même erreur apparaît pour le cas simple de
ggplot (data=mydataf, aes(levels(mydataf))) +
geom_bar()
il est donc clair que ggplot
interagit avec un seul vecteur. Je me gratte la tête, googler pour cette erreur donne un seul résultat .
Depuis que cette réponse a été fournie, des modifications significatives ont été apportées à la syntaxe ggplot
. Résumant la discussion dans les commentaires ci-dessus:
require(ggplot2)
require(scales)
p <- ggplot(mydataf, aes(x = foo)) +
geom_bar(aes(y = (..count..)/sum(..count..))) +
## version 3.0.0
scale_y_continuous(labels=percent)
Voici un exemple reproductible utilisant mtcars
:
ggplot(mtcars, aes(x = factor(hp))) +
geom_bar(aes(y = (..count..)/sum(..count..))) +
scale_y_continuous(labels = percent) ## version 3.0.0
Cette question est actuellement le hit n ° 1 sur Google pour "le nombre de ggplot par rapport à l'histogramme en pourcentage". J'espère que cela aide à distiller toutes les informations actuellement contenues dans les commentaires sur la réponse acceptée.
Remarque: Si hp
n'est pas défini comme facteur, ggplot renvoie:
ce code modifié devrait fonctionner
p = ggplot(mydataf, aes(x = foo)) +
geom_bar(aes(y = (..count..)/sum(..count..))) +
scale_y_continuous(formatter = 'percent')
si vos données contiennent des NA et que vous ne souhaitez pas les inclure dans l'intrigue, passez na.omit (mydataf) comme argument à ggplot.
j'espère que cela t'aides.
Avec ggplot2 version 2.1.0 c'est
+ scale_y_continuous(labels = scales::percent)
Depuis mars 2017, avec ggplot2
2.2.1, la meilleure solution est expliquée dans le livre de Hadley Wickham R for Data Science:
ggplot(mydataf) + stat_count(mapping = aes(x=foo, y=..prop.., group=1))
stat_count
calcule deux variables: count
est utilisé par défaut, mais vous pouvez choisir d'utiliser prop
qui affiche les proportions.
Si vous voulez que les pourcentages sur l'axe des ordonnées et soient marqués sur les barres:
library(ggplot2)
library(scales)
ggplot(mtcars, aes(x = as.factor(am))) +
geom_bar(aes(y = (..count..)/sum(..count..))) +
geom_text(aes(y = ((..count..)/sum(..count..)), label = scales::percent((..count..)/sum(..count..))), stat = "count", vjust = -0.25) +
scale_y_continuous(labels = percent) +
labs(title = "Manual vs. Automatic Frequency", y = "Percent", x = "Automatic Transmission")
Lors de l'ajout d'étiquettes à barres, vous pouvez souhaiter omettre l'axe des ordonnées pour un graphique plus propre, en ajoutant à la fin:
theme(
axis.text.y=element_blank(), axis.ticks=element_blank(),
axis.title.y=element_blank()
)
Voici une solution de contournement pour les données à facettes. (La réponse acceptée par @Andrew ne fonctionne pas dans ce cas.) L'idée est de calculer la valeur en pourcentage à l'aide de dplyr, puis d'utiliser geom_col pour créer le tracé.
library(ggplot2)
library(scales)
library(magrittr)
library(dplyr)
binwidth <- 30
mtcars.stats <- mtcars %>%
group_by(cyl) %>%
mutate(bin = cut(hp, breaks=seq(0,400, binwidth),
labels= seq(0+binwidth,400, binwidth)-(binwidth/2)),
n = n()) %>%
group_by(cyl, bin) %>%
summarise(p = n()/n[1]) %>%
ungroup() %>%
mutate(bin = as.numeric(as.character(bin)))
ggplot(mtcars.stats, aes(x = bin, y= p)) +
geom_col() +
scale_y_continuous(labels = percent) +
facet_grid(cyl~.)
C'est l'intrigue:
Si vous voulez un pourcentage étiquettes mais Ns réels sur l’axe des y, essayez ceci:
library(scales)
perbar=function(xx){
q=ggplot(data=data.frame(xx),aes(x=xx))+
geom_bar(aes(y = (..count..)),fill="orange")
q=q+ geom_text(aes(y = (..count..),label = scales::percent((..count..)/sum(..count..))), stat="bin",colour="darkgreen")
q
}
perbar(mtcars$disp)
Pour ceux qui y viendront après 2018, remplacez "labels = percent_format ()" par "scales :: percent"
Notez que si votre variable est continue, vous devrez utiliser geom_histogram (), car la fonction regroupera la variable par "bacs".
df <- data.frame(V1 = rnorm(100))
ggplot(df, aes(x = V1)) +
geom_histogram(aes(y = (..count..)/sum(..count..)))
# if you use geom_bar(), with factor(V1), each value of V1 will be treated as a
# different category. In this case this does not make sense, as the variable is
# really continuous. With the hp variable of the mtcars (see previous answer), it
# worked well since hp was not really continuous (check unique(mtcars$hp)), and one
# can want to see each value of this variable, and not to group it in bins.
ggplot(df, aes(x = factor(V1))) +
geom_bar(aes(y = (..count..)/sum(..count..)))