Ajouter les pvalues sur un ggplot, manuellement

A la fin d’une analyse de données, on réalise généralement un graph pour synthétiser les résultats obtenus. Par exemple, dans le cadre d’une ANOVA à un facteur (qui sert à comparer plusieurs moyennes), on pourrait vouloir réaliser ce genre de graph :

J’ai déjà évoqué, ici et plusieurs solutions pour ajouter les pvalues sur un ggplot, ou plus généralement pour ajouter les significativités des comparaisons (en utilisant les p-values, des lettres ou des étoiles), dans un ggplot.

Dans chacune de ces solutions, l’ajout était réalisé de façon plus ou moins automatisée, par l’utilisation d’une fonction.

Mais il existe des situations dans lesquelles ces fonctions ne peuvent pas être employées. C’est le cas, par exemple, lorsqu’on réalise une analyse de type Anova à deux facteurs en employant un GLM (parce que la réponse est de type comptage).

Je vais donc vous montrer comment ajouter les pvalues sur un ggplot, ou plus généralement comment ajouter du texte.

 

Prérequis

Pour tirer profit de cet article, je vous recommande de lire l’article: Introduction à la visualisation sous R avec le package ggplot2.

Principe de l'ajout manuel de texte

La méthode pour ajouter les pvalues sur un ggplot, ou n’importe quel texte, consiste à utiliser :

  • la fonction `geom_segment()` pour créer des traits horizontaux et verticaux (comme dans le plot juste au dessus),
  • la fonction `annotate()` (de ggplot2) pour ajouter le texte,
  • tâtonner pour définir les positions (les coordonnées x, y) des traits et du texte !

Tutoriel pour ajouter du texte de façon manuelle sur un ggplot

Les data utilisées

Pour vous montrer comment ajouter les pvalues sur un ggplot, de façon manuelle, je vais utiliser les données `warpbreaks` du package `dataset` chargé par défaut.

Ces données concernent le nombre de ruptures de chaîne par métier à tisser en fonction de 2 types de laines (A et B) et 3 niveaux de tension (High / Medium /Low).

data(warpbreaks)
head(warpbreaks)

    ##   breaks wool tension
    ## 1     26    A       L
    ## 2     30    A       L
    ## 3     54    A       L
    ## 4     25    A       L
    ## 5     70    A       L
    ## 6     52    A       L 

Nous pouvons visualiser les données, en utilisant ce graph :

library(ggplot2)
ggplot(warpbreaks, aes(x=tension, y=breaks, fill=wool, colour=wool))+
        geom_point(position=position_jitterdodge(dodge.width=0.7), size=2)+
        geom_boxplot(alpha=0.5,outlier.alpha=0)+
        xlab("")+
        ylab("Number of breaks")+
        theme_classic() 

Acquisition des pvalues

Imaginons que, pour une raison ou un autre, ce que nous souhaitons, c’est comparer les niveaux moyens de cassures (breaks) observées sur les laines de type A et B, pour chaque niveau de tension.C’est sans doute possible de le faire après ajustement d’un modèle complet de type anova à deux facteurs, puis en utilisant des contrasts, mais, ici, on va le faire plus simplement.On va réaliser tous les tests deux à deux, mais de façon automatisée ! (grâce aux fonctions map). Comme la variable `breaks` est une variable de comptage, c’est à dire une variable numérique entière discrète, il est nécessaire d’utiliser un glm, avec une distribution de poisson (ou quasi poisson en cas de surdispersion, comme c’est le cas ici).Pour plus de détail sur les glm sur données de comptage, vous pouvez consulter cet article.
library(tidyverse) # pour le pipe %>% 
library(car)# pour la fonction Anova


pval_glm_test <- warpbreaks %>% 
        split(.$tension) %>% 
        map(~glm(breaks~wool,family=quasipoisson, data=.)) %>% 
        map(Anova, test="F") %>% 
        map("Pr(>F)") %>% 
        map_dbl(1) 
Si vous ne comprenez pas le code allez voir cet article.
Pour corriger l’augmentation du risque alpha global lors de la réalisation de multiple comparaisons, je décide d’ajuster les p-values obtenues selon la méthode de Holm.
pval_glm_test_adj <- p.adjust(pval_glm_test, method="holm")

pval_glm_test_adj

##          L          M          H 
## 0.07350979 0.27927729 0.26743404 

Ajout des pvalues sur le ggplot

Le plot de base

g1 <- ggplot(warpbreaks, aes(x=tension, y=breaks, fill=wool, colour=wool))+
    geom_point(position=position_jitterdodge(dodge.width=0.7), size=2)+
    geom_boxplot(alpha=0.5,outlier.alpha=0)+
    xlab("")+
    ylab("Number of breaks")+
    scale_y_continuous(limits=c(0,100))+
    theme_classic() 

Création des traits pour le niveau low

Je décide d’indiquer la pvalue dans la partie supérieur du graph, entre les valeurs y=75 et y=100.

Il faut savoir que sur l’axe des x, le niveau L correspond à la valeur 1, le niveau M à la valeur 2, le niveau H à la valeur 3.

Pour réaliser ces traits, on utilise la couche `geom_segment()`

gL1 <- g1 +
    geom_segment(x=0.75, xend=1.25, y=80, yend=80, col="black") + # trait horizontal
    geom_segment(x=0.75, xend=0.75, y=80, yend=77, col="black") + # petit trait verticla à gauche 
    geom_segment(x=1.25, xend=1.25, y=80, yend=77, col="black") # petit trait vertical à droite

gL1 

La détermination des valeur x, xend, y, yend, se fait en tâtonnant un peu….

Ajout de la pvalue sur le ggplot pour le niveau low

Pour ajouter du texte sur le ggplot, on utilise la fonction annotate

gL2 <- gL1 +
    annotate("text", x = 1, y = 85, label = "p = 0.074")
gL2 

Pour l'ensemble des niveaux

Il suffit alors de faire la même chose pour l’ensemble des niveaux

gfinal <- g1 +
    ##### Niveau Low 
    geom_segment(x=0.75, xend=1.25, y=80, yend=80, col="black") + # trait horizontal
    geom_segment(x=0.75, xend=0.75, y=80, yend=77, col="black") + # petit trait verticla à gauche 
    geom_segment(x=1.25, xend=1.25, y=80, yend=77, col="black")+ # petit trait vertical à droite
    annotate("text", x = 1, y = 85, label = "p = 0.074")+
        
    ##### Niveau Medium 
    geom_segment(x=1.75, xend=2.25, y=80, yend=80, col="black") + # trait horizontal
    geom_segment(x=1.75, xend=1.75, y=80, yend=77, col="black") + # petit trait verticla à gauche 
    geom_segment(x=2.25, xend=2.25, y=80, yend=77, col="black")+ # petit trait vertical à droite
    annotate("text", x = 2, y = 85, label = "p = 0.28")+
        
    ##### Niveau High
    geom_segment(x=2.75, xend=3.25, y=80, yend=80, col="black") + # trait horizontal
    geom_segment(x=2.75, xend=2.75, y=80, yend=77, col="black") + # petit trait verticla à gauche 
    geom_segment(x=3.25, xend=3.25, y=80, yend=77, col="black")+ # petit trait vertical à droite
    annotate("text", x = 3, y = 85, label = "p = 0.27") 
Que pensez vous de cette solution ? Si vous en avez une autre, indiquez la moi en commentaire.
Si cet article vous a plu, ou vous a été utile, et si vous le souhaitez, vous pouvez soutenir ce blog en faisant un don sur sa page Tipeee 🙏

3 réponses

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.