Data visualisation des variables catégorielles

Pour faire suite à un premier article concernant la description des variables catégorielles, publié il y a quelques semaines, je vais vous présenter, dans ce billet, quelques visualisations particulièrement adaptées à la représentation graphique de ce type de données. J’en utilise classiquement trois :
  • les mosaic plots
  • les bar plots
  • et les stacked bar plots.
Pour illustrer cela, je vais employer le même jeu de données que celui du premier article, c’est à dire le jeu de données Melanoma2 que j’ai créé à partir du jeu de données Melanoma du package MASS

1. Les Données

library(MASS)

Melanoma$status <- as.factor(Melanoma$status)
Melanoma$sex <- as.factor(Melanoma$sex)
Melanoma$ulcer <- as.factor(Melanoma$ulcer)

Melanoma2 <- Melanoma


levels(Melanoma2$status)[c(1,2,3)] <- c("dcd_Melanome", "vivant", "dcd_autres")
levels(Melanoma2$sex)[c(1,2)] <- c("F", "M")
levels(Melanoma2$ulcer)[c(1,2)] <- c("Non", "Oui")


head(Melanoma2)

##   time       status sex age year thickness ulcer
## 1   10   dcd_autres   M  76 1972      6.76   Oui
## 2   30   dcd_autres   M  56 1968      0.65   Non
## 3   35       vivant   M  41 1977      1.34   Non
## 4   99   dcd_autres   F  71 1968      2.90   Non
## 5  185 dcd_Melanome   M  52 1965     12.08   Oui
## 6  204 dcd_Melanome   M  28 1971      4.84   Oui
 

2. Les Mosaic plots

Les mosaic plots sont particulièrement adaptés pour représenter les fréquences ou les pourcenatges des combinaisons de 2 variables catégorielles (voir le premier article).Les fréquences sont reportées sur l’axe des Y, alors que l’axe des X comporte les modalités d’une des variables. La seconde variables est représentées par des sous divisions sur l’axe des Y. La somme des fréquences pour chaque modalité de la variable représentée en X vaut 1. Les surfaces des combinaison des deux variables sont proportionnelles à leur fréquence globale. Par exemple ici, le mosaic plot de la combinaison des variables ulcer et sexe :Les mosaic plot peuvent être réalisés très facilement avec le package ggmosaic.
library(ggplot2)
library(ggmosaic)

ggplot(Melanoma2)+
    geom_mosaic(aes(x=product(sex,ulcer), fill=sex))+
    ylab("Frequence")+
    xlab("ulcer")+
    ggtitle("Répartition des données en fonction du sexe\net de la présence ou non d'un ulcer")
data visualisation variables catégoriellesLes couleurs peuvent facilement être changées grâce à l’addin Colour Picker comme expliqué ici.Cela est très utile pour, par exemple, mettre au second plan les données du sexe masculin en employant une couleur grise.
ggplot(Melanoma2)+
        geom_mosaic(aes(x=product(sex,ulcer), fill=sex))+
        ylab("Frequence")+
        xlab("Ulcer")+
        ggtitle("Répartition des données en fonction du sexe\net de la présence ou non d'un ulcer")+
        scale_fill_manual(values=c("#EE00EE", "#636363"))
data visualisation variables catégoriellesPour changer l’ordre des modalités, par exemple pour que “Ulcer=oui” apparaisse en premier, on peut utiliser la fonctionrelevel, comme ceci:
Melanoma2$ulcer <- relevel(Melanoma2$ulcer, ref="Oui")

ggplot(Melanoma2)+
     geom_mosaic(aes(x=product(sex,ulcer), fill=sex))+
     ylab("Frequence")+
     xlab("Ulcer")+
     ggtitle("Répartition des données en fonction du sexe\net de la présence ou non d'un ulcer")+
     scale_fill_manual(values=c("#EE00EE", "#636363"))
Lorsque la variable catégorielle a plus de deux modalités, comme par exemple la variable status, on peut utiliser la fonction ordered pour définir l’ordre de toutes les modalités. D’abord le mosaic plot avec l’ordre par défaut :
ggplot(Melanoma2)+
    geom_mosaic(aes(x=product(sex,status), fill=sex), offset = 0.05)+
    ylab("Frequence")+
    xlab("Ulcer")+
    ggtitle("Répartition des données en fonction du sexe\net du status")+
    scale_fill_manual(values=c("#EE00EE", "#636363"))+
    theme(axis.text.x = element_text(angle=30, hjust=1, vjust=1))
data visualisation variables catégoriellesPuis le mosaic plot après la modification de l’ordre des modalités ou niveaux (ou encore levels) de la variable catégorielle status par l’utilisation de la fonction ordered:
levels(Melanoma2$status)

## [1] "dcd_Melanome" "vivant"       "dcd_autres"

Melanoma2$status <- ordered(Melanoma2$status, levels=c("vivant", "dcd_autres", "dcd_Melanome"))

levels(Melanoma2$status)

## [1] "vivant"       "dcd_autres"   "dcd_Melanome"

ggplot(Melanoma2)+
   geom_mosaic(aes(x=product(sex,status), fill=sex), offset = 0.05)+
   ylab("Frequence")+
   xlab("Ulcer")+
   ggtitle("Répartition des données en fonction du sexe\net du status")+
   scale_fill_manual(values=c("#EE00EE", "#636363"))+
   theme(axis.text.x = element_text(angle=30, hjust=1, vjust=1))
data visualisation variables catégoriellesLes espaces entres les différentes zones ont été augmentés à l’aide de l’argument offset (valeur par défauut fixée à 0.01) de la fonction geom_mosaic.Pour plus de détail sur le package ggmosaic, consultez [sa vignette].(<https://cran.r-project.org/web/packages/ggmosaic/vignettes/ggmosaic.html>) 

3. Les bar plots

Les bar plots ne doivent pas être employés pour représenter des données numériques continues, parce qu’ils ne permettent pas :
  • de visualiser la distribution des données
  • de visualiser leur dispersion
  • de visualiser une éventuelle asymétrie des données
  • de mettre en évidence la présence de donées extrêmes (outliers)
  • d’identifier les nombre de données sur lesquels ils reposent.
Pour une bonne démonstration de ces éléments, je vous conseille d’aller voir cet article.En revanche, les bar plots sont tout à fait adaptés pour représenter des pourcentages avec leurs intervalles de confiance.Les bar plots peuvent être réalisés très facilement avec le package ggplot2. Pour cela, il est nécessaire de disposer d’un tableau de données avec:
  • une ligne par modalité (ou combinaison de modalités),
  • une colonne contenant les pourcentages,
  • une colonne contenant les bornes inférieures de l’intervalle de confiance,
  • une colonne contenant les bornes supérieures de l’intervalle de confiance,
  • une colonne contenant les modalités de la première variable catégorielle,
  • une colonne contenant les modalités de la seconde variable catégorielle.
Je reprends ici l’exemple de l’article sur la description des variables catégorielles dans lequel je calculais les pourcentages d’hommes et de femmes pour chacune des modalités de la variable status, ainsi que leurs intervalles de confiance. J’ai simplement ajouté, dans le tableau final, les variables sex et status afin de les utiliser comme axe des X et comme argument decouleur.
library(binom)
options(digits=2)

TC <- with(Melanoma2, table(status, sex,useNA = "ifany"))

# affichage des fréquences pour lesquelles on veut calculer un IC
prop.table(TC,1) 

##               sex
## status            F    M
##   vivant       0.68 0.32
##   dcd_autres   0.50 0.50
##   dcd_Melanome 0.49 0.51

# on récupère le nb d'observations pour les femmes pour tous les status
nb.F <- as.vector(TC[,1]) 

# idem pour les hommes
nb.M <- as.vector(TC[,2])

# on récupère le nombre total d'observations pour chaque status
nbT <- rowSums(TC)

# on calcule les IC pour les fréquences de femmes
df.F <- binom.confint(nb.F, nbT, conf.level=0.95, methods="prop.test")
rownames(df.F) <- paste("F", rownames(TC), sep="__")

# on affiche le tableau obtenu pour les femmes
df.F

##                    method  x   n mean lower upper
## F__vivant       prop.test 91 134 0.68  0.59  0.76
## F__dcd_autres   prop.test  7  14 0.50  0.27  0.73
## F__dcd_Melanome prop.test 28  57 0.49  0.36  0.63

# idem pour les hommes
df.M <- binom.confint(nb.M, nbT, conf.level=0.95, methods="prop.test")
rownames(df.M) <- paste("M", rownames(TC), sep="__")
df.M

##                    method  x   n mean lower upper
## M__vivant       prop.test 43 134 0.32  0.24  0.41
## M__dcd_autres   prop.test  7  14 0.50  0.27  0.73
## M__dcd_Melanome prop.test 29  57 0.51  0.37  0.64

# on colle les lignes
df<-rbind(df.F, df.M)


# on crée les variables sex et status en utilisant les rownames du data.frame
df$sex <- substr(rownames(df),1,1)
df$status <- substr(rownames(df),4,100)

df

##                    method  x   n mean lower upper sex       status
## F__vivant       prop.test 91 134 0.68  0.59  0.76   F       vivant
## F__dcd_autres   prop.test  7  14 0.50  0.27  0.73   F   dcd_autres
## F__dcd_Melanome prop.test 28  57 0.49  0.36  0.63   F dcd_Melanome
## M__vivant       prop.test 43 134 0.32  0.24  0.41   M       vivant
## M__dcd_autres   prop.test  7  14 0.50  0.27  0.73   M   dcd_autres
## M__dcd_Melanome prop.test 29  57 0.51  0.37  0.64   M dcd_Melanome


## plot
ggplot(df, aes(x=status,y=mean*100, fill=sex))+
    geom_bar(position=position_dodge(), stat="identity") +
    geom_errorbar(aes(ymin=lower*100, ymax=upper*100),width=.2,position=position_dodge(.9))+
    scale_y_continuous(limits=c(0,100))+
    ylab("Pourcentage")+
    theme_classic()
data visualisation variables catégoriellesLà aussi on peut réordonner les niveaux de la variable status pour, par exemple, afficher la modalité vivant en premier, et modifier les couleurs.
df$status <- ordered(df$status, levels=c("vivant", "dcd_autres", "dcd_Melanome"))

ggplot(df, aes(x=status,y=mean*100, fill=sex))+
    geom_bar(position=position_dodge(), stat="identity") +
    geom_errorbar(aes(ymin=lower*100, ymax=upper*100),width=.2, position=position_dodge(.9))+
    ylab("Pourcentage")+
    scale_y_continuous(limits=c(0,100))+
    scale_fill_manual(values=c("#32CD32", "#4876FF"))+
    theme_classic()
data visualisation variables catégorielles

4. Les Stacked bar plot

Il existe un autre type de bar plot qui peut être utilisé pour représenter des fréquences ou des pourcentage : le “proportional stacked bar plot”. Ca ressemble assez au mosaic plot, sauf que les barres associées aux modalités d’une des variables catégorielles ont toutes la même largeur, elles ne sont pas proportionnelles à leurs fréquences globales. Ci dessous un exemple pour visualiser les pourcentages des différentes modalités de la variable status (vivant, dcd_autres, dcd_Melanome) par sexe.Dans un premier temps, il est nécessaire de créer un tableau de données (data.frame) avec les pourcentages correspondant. Pour chaque sexe, la somme des pourcentages relatifs aux modalités de la variable status doit être égale à 1. Pour cela , on utilise les fonctions table, prop.table décrites dans le premier article sur l’analyse descriptive des variables catégorielles.
TC <- table(Melanoma2$status, Melanoma2$sex,useNA = "ifany")
df2 <- prop.table(TC,2)
df2 <- df2*100
df2 <- round (df2, 2)
df2 <- as.data.frame(df2)
names(df2) <- c("status", "sex", "p")

df2

##         status sex    p
## 1       vivant   F 72.2
## 2   dcd_autres   F  5.6
## 3 dcd_Melanome   F 22.2
## 4       vivant   M 54.4
## 5   dcd_autres   M  8.9
## 6 dcd_Melanome   M 36.7
On peut ensuite réaliser le plot en utilisant la fonction geom_bar. L’ordre des modalités est géré par l’argument limits de la fonction scale_fill_manual.
ggplot(df2, aes(x=sex, y=p, fill=status)) +    
   geom_bar(stat="identity", position="stack", width=0.5) +
   coord_flip()+
   xlab("sexe")+
   ylab("pourcentage")+
   scale_fill_manual(values=c("#BAB1B1","#87CEFA","#1C86EE"),limits=c("dcd_Melanome", "dcd_autres", "vivant"))+
   theme_classic()
Et les pie charts (plot en camembert) me direz vous ?Je n’aime pas les utiliser car lorsqu’il y a plus de 3 ou 4 catégories, ils sont parfois difficiles à lire.

5. Pour aller plus loin

Si vous vous intéressez à la visualisation des données, je vous recommande d’aller jeter un coup d’oeil : Et vous, utilisez vous d’autres visualisations pour représenter vos variables catégorielles ? Si oui partagez les en commentaire !Dans tous les cas, j’espère que cet article vous permettra de représenter plus facilement et plus efficacement vos variables catégorielles. Si cet article vous a plu, ou vous a été utile, et si vous le souhaitez, vous pouvez me remercier en faisant un don sur ma page Tipeee 🙏👉 Cliquez ici pour faire un don Retrouvez ici 3 de mes articles les plus consultés:12 conseils pour organiser efficacement vos données dans un tableurComment insérer des références bibliographiques dans un document Rmarkdown ?Comment retrouver sous R une couleur employée avec Excel ?

5 réponses

  1. Très instructif ! Merci Claire !

    Sinon je cherche le code à écrire pour visualiser le pourcentage de réponse « oui » par exemple , dans plusieurs variables grâce à un barplot ( circular ou lollipop de préférence)

  2. Bonjour Claire

    super article encore! merci beaucoup.
    Juste un détail qui m’échappe. Dans la partie sur les barplots : on crée les variables sex et status en utilisant les rownames du data.frame
    df$sex <- substr(rownames(df),1,1)
    df$status <- substr(rownames(df),4,100)

    je n'arrive pas à comprendre d'où viennent 1,1 et 4, 100

    Merci encore

    1. Bonjour Nathalie,

      Dans la commande substr(rownames(df),1,1), le premier 1 correspond à la première position du motif à récupérer, et le deuxième 1, correspond à la dernière position de ce motif. Ici comme on veut récupérer uniquement la première lettre, c’est 1 et 1.
      Dans la command df$status <- substr(rownames(df),4,100), c'est pareil, le 4 correspond à la position de début du découpage, et je pense que 100 est arbitraire pour être sûre d'avoir l'ensemble du motif. J'espère que cela vous aide. Bonne continuation

  3. theme(axis.text.x = element_text(angle=30, hjust=1, vjust=1))

    Vous avez ssauvez ma vie avec ça! j, ai cherche comment representer les effectif pour une variable province avec 26 modalités. j, obtenai de barres mais les modalilités de la variables apparaissaient en axis tres serrées . j, ai cherché comment les placer en verticale inclinées. merci

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Bonjour !

vous venez souvent ?

Identifiez-vous pour avoir accès à toutes les fontionnalités !

Aide mémoire off'R ;)

Enregistrez vous pour recevoir gratuitement mes fiches “aide mémoire” (ou cheat sheets) qui vous permettront de réaliser facilement les principales analyses biostatistiques avec le logiciel R et pour être informés des mises à jour du site.