web-dev-qa-db-fra.com

Afficher les% au lieu des nombres dans les graphiques des variables catégoriques

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

147
wishihadabettername

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

 enter image description here

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:

 enter image description here

204
Andrew

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.

55
Ramnath

Avec ggplot2 version 2.1.0 c'est

+ scale_y_continuous(labels = scales::percent)
42
Fabian Hertwig

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.

30
Olivier Ma

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

 enter image description here

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

 enter image description here

18
Sam Firke

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:

 enter image description here

6
ACNB

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)
6
Steve Powell

Pour ceux qui y viendront après 2018, remplacez "labels = percent_format ()" par "scales :: percent"

3
Ghazal

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..))) 
0
Rtist