web-dev-qa-db-fra.com

Comment obtenir un graphique à barres avec plusieurs variables côte à côte, regroupées par un facteur

J'ai un jeu de données qui ressemble à celui-ci ci-dessous. J'essaie de créer un diagramme en barres avec la variable de regroupement genre, avec toutes les variables côte à côte sur l'axe des x (groupées par sexe comme facteur de remplissage avec des couleurs différentes) et les valeurs moyennes des variables sur l'axe des y (représentant essentiellement des pourcentages)

tea                coke            beer             water           gender
14.55              26.50793651     22.53968254      40              1
24.92997199        24.50980392     26.05042017      24.50980393     2
23.03732304        30.63063063     25.41827542      20.91377091     1   
225.51781276       24.6064623      24.85501243      50.80645161     1
24.53662842        26.03706973     25.24271845      24.18358341     2   

En fin de compte, je veux obtenir un barplot comme celui-ci enter image description here

des suggestions comment faire cela? J'ai fait des recherches mais je ne trouve que des exemples de facteurs sur l'axe des x, pas de variables groupées par un facteur. toute aide serait appréciée!

29
roscoe1895

Vous pouvez utiliser l'agrégat pour calculer les moyennes:

means<-aggregate(df,by=list(df$gender),mean)
Group.1      tea     coke     beer    water gender
1       1 87.70171 27.24834 24.27099 37.24007      1
2       2 24.73330 25.27344 25.64657 24.34669      2

Débarrassez-vous de la colonne Group.1

means<-means[,2:length(means)]

Ensuite, vous devez reformater les données pour qu'elles soient au format long:

library(reshape2)
means.long<-melt(means,id.vars="gender")
  gender variable    value
1      1      tea 87.70171
2      2      tea 24.73330
3      1     coke 27.24834
4      2     coke 25.27344
5      1     beer 24.27099
6      2     beer 25.64657
7      1    water 37.24007
8      2    water 24.34669

Enfin, vous pouvez utiliser ggplot2 pour créer votre tracé:

library(ggplot2)
ggplot(means.long,aes(x=variable,y=value,fill=factor(gender)))+
  geom_bar(stat="identity",position="dodge")+
  scale_fill_discrete(name="Gender",
                      breaks=c(1, 2),
                      labels=c("Male", "Female"))+
  xlab("Beverage")+ylab("Mean Percentage")

enter image description here

43

Vous pouvez tracer les moyennes sans recourir à des calculs externes et à des tables supplémentaires en utilisant stat_summary(...). En fait, stat_summary(...) a été conçu pour ce que vous faites exactement.

library(ggplot2)
library(reshape2)            # for melt(...)
gg <- melt(df,id="gender")   # df is your original table
ggplot(gg, aes(x=variable, y=value, fill=factor(gender))) + 
  stat_summary(fun.y=mean, geom="bar",position=position_dodge(1)) + 
  scale_color_discrete("Gender")
  stat_summary(fun.ymin=min,fun.ymax=max,geom="errorbar",
               color="grey80",position=position_dodge(1), width=.2)

Pour ajouter des "barres d'erreur", vous pouvez également utiliser stat_summary(...) (ici, j'utilise les valeurs min et max plutôt que sd car vous avez si peu de données).

ggplot(gg, aes(x=variable, y=value, fill=factor(gender))) + 
  stat_summary(fun.y=mean, geom="bar",position=position_dodge(1)) + 
  stat_summary(fun.ymin=min,fun.ymax=max,geom="errorbar",
               color="grey40",position=position_dodge(1), width=.2) +
  scale_fill_discrete("Gender")

9
jlhoward

En utilisant reshape2 et dplyr. Vos données:

df <- read.table(text=
"tea                coke            beer             water           gender
14.55              26.50793651     22.53968254      40              1
24.92997199        24.50980392     26.05042017      24.50980393     2
23.03732304        30.63063063     25.41827542      20.91377091     1   
225.51781276       24.6064623      24.85501243      50.80645161     1
24.53662842        26.03706973     25.24271845      24.18358341     2", header=TRUE)

Obtenir des données sous forme correcte:

library(reshape2)
library(dplyr)
df.melt <- melt(df, id="gender")
bar <- group_by(df.melt, variable, gender)%.%summarise(mean=mean(value))

Traçage:

library(ggplot2)
ggplot(bar, aes(x=variable, y=mean, fill=factor(gender)))+
  geom_bar(position="dodge", stat="identity")

enter image description here

3
Carlos Cinelli