Tutoriel : le test de Friedman

Pour faire suite au tutoriel dédié à l’ANOVA sur mesures répétées, je vous propose un tutoriel sur son alternative non paramétrique : le test de Friedman !Etant une alternative non paramétrique à l’ANOVA sur mesures répétées, le test de Friedman doit être employé lorsque l’hypothèse de normalité des résidus n’est pas satisfaite. Cette situation se rencontre classiquement lorsque la variable réponse est un score, ou encore une variable ordinale comme un classement.

Data

Pour illustrer cet article nous allons justement envisager, non plus des données longitudinales (comme dans l’article sur l’ANOVA pour mesures répétées – nous aurions également pu employer le test de Friedman), mais des données ordinales. Nous allons considérer que nous avons demandé à 12 personnes de classer quatre gâteaux (citron, vanille, chocolat et pomme) selon leur préférences (le rang 1 correspondant au gâteau préféré), et que nous avons obtenus ces résultats:

mydata

    ##    sujet Gateau_citron Gateau_vanille Gateau_chocolat Gateau_pomme
    ## 1    S_1           4.0            3.0             2.0          1.0
    ## 2    S_2           4.0            2.0             3.0          1.0
    ## 3    S_3           3.0            1.5             1.5          4.0
    ## 4    S_4           3.0            1.0             2.0          4.0
    ## 5    S_5           4.0            2.0             1.0          3.0
    ## 6    S_6           2.0            2.0             2.0          4.0
    ## 7    S_7           1.0            3.0             2.0          4.0
    ## 8    S_8           2.0            4.0             1.0          3.0
    ## 9    S_9           3.5            1.0             2.0          3.5
    ## 10  S_10           4.0            1.0             3.0          2.0
    ## 11  S_11           4.0            2.0             3.0          1.0
    ## 12  S_12           3.5            1.0             2.0          3.5 

Visualisation

La visualisation de ce type de données n’est pas aisée. Même si je ne suis pas très satisfaite, j’ai choisi de faire apparaître toutes les données, ainsi que la moyenne des rangs pour chaque gâteau (losange rouge) :

library(tidyverse)
mydataL <- mydata %>% 
        pivot_longer(-sujet,names_to = "Gateau", values_to = "rang")

mydataL$Gateau<-fct_inorder(mydataL$Gateau)



ggplot(mydataL, aes(y=rang, x=Gateau, fill=Gateau, colour=Gateau))+
    geom_jitter(size=3, height=0, width=0.05,show.legend=FALSE)+
    stat_summary(fun.y=mean, geom="point", colour="#eb4d55", size=7,show.legend=FALSE, shape=18)+
    scale_colour_manual(values=c("#FFD700", "#EE9A00", "#8B4513", "#32CD32"))+
    theme_minimal()+
    ggtitle("Rang moyen (losange rouge)") 
données ordinales

Remarque : Si vous avez d’autres suggestions, n’hésitez pas à les partager en écrivant un  commentaire à la fin de cet article.

D’après ce graphique, le gâteau préféré est celui à la vanille, suivi de très près par le gâteau au chocolat. Viennent ensuite le gâteau au pommes puis le gâteau au citron.

Les moyennes des rangs peuvent être obtenues comme ceci :

mydataL %>% 
    group_by(Gateau) %>% 
    summarise(moy_rang=mean(rang))

    ## # A tibble: 4 x 2
    ##   Gateau          moy_rang
    ##                 
    ## 1 Gateau_citron       3.17
    ## 2 Gateau_vanille      1.96
    ## 3 Gateau_chocolat     2.04
    ## 4 Gateau_pomme        2.83 

Question

On se demande alors si un (ou plusieurs gâteaux) est systématiquement mieux classé (c’est-à-dire préféré aux autres gâteaux). Autrement dit, est-ce que cette préférence que l’on devine à la visualisation est significative ou non ? Et si c’est le cas, on aimerait ensuite comparer les gâteaux deux à deux pour savoir si l’un d’entre eux est toujours préféré, ou bien si certains gâteaux sont comparables en termes de préférence.

Test de Friedman

Statistique du test

La statistique du test de Friedman est définie par :\[\chi^{2}_{R} =  \frac{12}{n \times  k(k+1)} \sum_{j=1}^{k}R_j^2  – 3n\times (k+1)\]Avec
  • n: la taille des k échantillons appariés.
  • R\_j : la somme des rangs pour l’échantillon j (Temps j).
Cette statistique est distribuée selon une loi du Chi2 à k-1 degrés de liberté.

Hypothèses

  • H0 : les 4 gâteaux ont des scores identiques ; autrement dit aucun gâteaux n’est préféré.
  • H1 : au moins un des gâteaux tend à obtenir des scores plus faibles que les autres; autrement dit au moins un des gâteaux est préféré aux autres.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Réalisation du test avec R

Pour réaliser le test de Friedman, nous pouvons utiliser la fonction friedman.test() du package stats (chargé par défaut à chaque ouverture de session).

Le terme | sujet permet d’indiquer que les 4 gâteaux ont été classés par les mêmes sujets.  Autrement dit, de lier les scores attribués pour chaque gâteau à une personne donnée.

   friedman.test(rang ~ Gateau | sujet, data=mydataL)

    ## 
    ##  Friedman rank sum test
    ## 
    ## data:  rang and Gateau and sujet
    ## Friedman chi-squared = 8.0973, df = 3, p-value = 0.04404 

Ici, la p-value est 0.05, l’hypothèse nulle est donc rejetée. Le corollaire est que l’hypothèse alternative est acceptée. De ce fait, nous pouvons conclure qu’au moins un des gâteaux est préféré.

Comparaisons multiples

Toutes les comparaisons deux à deux

Pour réaliser toutes les comparaisons deux à deux après un test de Friedman, nous pouvons utiliser un test post hoc de Conover, avec ajustement des p-values selon la méthode de Holm.
Ce test est disponible en utilisant la fonction frdAllPairsConoverTest() du package PMCMRplus.

 

Remarque : Il est nécessaire d’installer ce package avant de le charger. Pour cela, vous pouvez aller dans l’onglet “Packages” de la fenêtre en bas à droite de R Studio. Puis cliquer sur Install, et indiquez le nom du package désiré. Vous trouverez un exemple d’installation de package dans le deuxième paragraphe de cet article.

Les données doivent être présentées sous la forme d’une matrice, sans la variable Sujet, mais avec un nom de ligne :

 mymat <- mydata %>% 
             dplyr::select(-sujet) %>%
             as.matrix() 

rownames(mymat) <- 1:12
mymat

    ##    Gateau_citron Gateau_vanille Gateau_chocolat Gateau_pomme
    ## 1            4.0            3.0             2.0          1.0
    ## 2            4.0            2.0             3.0          1.0
    ## 3            3.0            1.5             1.5          4.0
    ## 4            3.0            1.0             2.0          4.0
    ## 5            4.0            2.0             1.0          3.0
    ## 6            2.0            2.0             2.0          4.0
    ## 7            1.0            3.0             2.0          4.0
    ## 8            2.0            4.0             1.0          3.0
    ## 9            3.5            1.0             2.0          3.5
    ## 10           4.0            1.0             3.0          2.0
    ## 11           4.0            2.0             3.0          1.0
    ## 12           3.5            1.0             2.0          3.5

 
frdAllPairsConoverTest(mymat,p.adjust = "holm")

    ##                 Gateau_citron Gateau_vanille Gateau_chocolat
    ## Gateau_vanille  0.15          -              -              
    ## Gateau_chocolat 0.18          1.00           -              
    ## Gateau_pomme    1.00          0.40           0.40 
Lorsque toutes les comparaisons sont réalisées deux à deux, et que les p-values sont ajustées en conséquences aucune différence n’apparaît significative.

Toutes les comparaisons à un groupe

Dans certaines situations, on peut être intéressé uniquement par les comparaisons deux à deux avec un groupe de référence (le gâteau au citron par exemple). Dans ce cas là, une astuce peut consister à :

  • réaliser toutes les comparaisons deux à deux sans ajuster les p-values,
  • ne garder que les p-values correspondant aux comparaisons souhaitées (tous les gâteaux vs le gâteau citron)
  • ajuster ces p-values, par la méthode de Holm par exemple.
all_pval <- frdAllPairsConoverTest(mymat,p.adjust = "none")
all_pval

    ##                 Gateau_citron Gateau_vanille Gateau_chocolat
    ## Gateau_vanille  0.025         -              -              
    ## Gateau_chocolat 0.037         0.873          -              
    ## Gateau_pomme    0.523         0.099          0.135

    # selection des pvalues de la colonne1
    pval_kept <- all_pval$p.value[,1]
    pval_kept

    ##  Gateau_vanille Gateau_chocolat    Gateau_pomme 
    ##      0.02542119      0.03652739      0.52287258

    # ajustement des pvalues selectionnes
    pval_kept_adjust <-  p.adjust(pval_kept, method="holm") 
    pval_kept_adjust

    ##  Gateau_vanille Gateau_chocolat    Gateau_pomme 
    ##      0.07626358      0.07626358      0.52287258 
Lorsque seules les comparaisons par rapport au gâteau au citron sont réalisées, les p-values obtenues demeurent au-dessus du seuil de signification de 0.05, mais ont largement diminuées.Cela est dû au fait que la correction de ces p-values, pour contre-carrer l’augmentation du risque alpha global, est moins importante puisqu’il y a moins de comparaisons à corriger (par rapport à la situation dans laquelle toutes les comparaisons deux à deux sont réalisées). Ici, on peut envisager qu’avec plus de sujet interrogés, il serait sans doute possible de mettre en évidence des différences significatives entre les gâteaux.Et pour ajouter les p-values sur votre représentation graphique, vous pouvez vous inspirer de cet article.

Conclusion

J’espère qu’avec ce tutoriel, en complément de celui dédié à l’ANOVA sur mesures répétées, vous  n’aurez plus de difficultés à analyser vos données répétées selon une variable catégorielle, et que vous saurez choisir entre les deux méthodes.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 🙏

Image par Larry White de Pixabay

18 réponses

  1. Bonjour,
    un grand bravo pour votre travail, j’adore votre site, cela m’aide énormément.

    Une question : lorsque les hypothèses ne sont pas respectées pour faire une anova, comment choisir entre un test de friedman et une transformation box cox ?
    Merci,
    Lorène

    1. Bonjour Lorene,

      ma façon de voir les choses et d’utiliser une méthode non paramétrique lorsqu’elle existe, plutôt que la transformation. C’est le cas ici, donc j’utiliserai Friedman en cas de non normalité des données.
      Bonne continuation.

  2. Morning dear. My comment is not straightly related to this article. I like what you are doing so that we learn many things about data analysis. I was wondering if it possible to download your articles, maybe in pdf format, in order to review it when it will be necessary, without having to seek for your blog necessary.

  3. S’il vous plait Madame, quelle version de R utilisez-vous, quelles sont les packages à installer et les retrouvent-ont? J’ai compilé le premier code sous Rstudio mais bon nombre de fonctions me sont inconnues.

    Merci.

    Cordialement,

    1. Voici les infos. Bonne continuation

      sessionInfo()
      R version 3.6.1 (2019-07-05)
      Platform: x86_64-w64-mingw32/x64 (64-bit)
      Running under: Windows 10 x64 (build 18362)

      Matrix products: default

      locale:
      [1] LC_COLLATE=French_France.1252 LC_CTYPE=French_France.1252
      [3] LC_MONETARY=French_France.1252 LC_NUMERIC=C
      [5] LC_TIME=French_France.1252

      attached base packages:
      [1] stats graphics grDevices utils datasets methods base

      loaded via a namespace (and not attached):
      [1] compiler_3.6.1 tools_3.6.1 packrat_0.5.0

  4. Bonjour,

    Petit ajout d’un T pour la fonction frdAllPairsConoverTes() afin de ne pas avoir d’erreur de code 🙂

    “Pour réaliser toutes les comparaisons deux à deux après un test de Friedman, nous pouvons utiliser un test post hoc de Conover, avec ajustement des p-values selon la méthode de Holm.
    Ce test est disponible en utilisant la fonction frdAllPairsConoverTes() du package PMCMRplus”

    Merci encore pour votre blog !!!

  5. Bonjour,
    Merci pour votre blog qui est très utile à chacun de nous.
    Est-il possible d’utiliser le test de Friedman sur une variable discontinue (comptage du nombre de vivant) ?
    En effet il m’apparait que l’anova sur mesure répétée est la meilleur solution pour tester la différence de mortalité des descendants de plusieurs parents (ayant 1 duplicat) mais étant donné que la variable de mortalité est une variable discontinue, l’ANOVA n’est pas possible. Le test non-paramétrique est donc la solution ?
    Je vous remercie,
    Et surtout votre blog est super !

    1. Bonjour,

      Est-ce que par discontinue vous voulez dire discrète ?
      D’après ma compréhension de voter question, oui je pense que vous pouvez employer le test de Friedman.
      Sinon, un GLMM avec une distribution de Poisson.
      Bonne continuation

  6. Bonjour,
    Je vous remercie pour toutes ces informations, très utiles pour une novice comme moi… Petite question de béotienne : comment se fait-il que l’on puisse obtenir une p-value qui permet de rejeter l’hypothèse Ho au test de Friedman puis ensuite ne trouver aucune différence significative entre les paires (ou au moins une paire) au test de Conover ? Le test de Friedman indique qu’au moins un gâteau est préféré mais aucune moyenne par gâteau ne diffère d’une autre (Conover) ?
    autre question: existe-t-il un test non paramétrique qui permettrait en même temps de tester des effets d’interaction entre deux facteurs ?

    En vous remerciant pour tout ce travail !
    Bien cdlt,

    1. Bonjour,

      c’est parce que les tests entre les paires sont ajustées, les pvalues sont “recalibrées” pour avoir un risque alpha global de 5%, et puis aussi parce que la puissance est moindre puisque le nombre de données est limité aux deux groupes comparés.
      A ma connaissance, non, on ne peut pas tester l’interaction.
      Une solution à creuser peut consister à employer un test par permuations…
      Bonne continuation

  7. Bonjour Claire,
    article très intéressant et explicite comme d’habitude, encore merci. Le test de Friedman peut elle être appliqué dans le cas de données appariés ne satisfaisant pas les conditions de normalité et dont la variable étudiée n’est pas ordinale.
    Un exemple de mes données
    ID Tube Var
    1 Tube 1 90450
    2 Tube 1 90915
    3 Tube 1 76666
    4 Tube 1 70470
    5 Tube 1 108416
    6 Tube 1 89443
    7 Tube 1 87740
    8 Tube 1 84952
    9 Tube 1 76743
    10 Tube 1 81235
    11 Tube 1 84177
    12 Tube 1 102995
    13 Tube 1 92463
    14 Tube 1 105551
    15 Tube 1 112830
    1 Tube 2 81854
    2 Tube 2 88359
    3 Tube 2 75349
    4 Tube 2 70006
    5 Tube 2 105783
    6 Tube 2 86965
    7 Tube 2 85184
    8 Tube 2 78137
    9 Tube 2 96026
    10 Tube 2 81699
    11 Tube 2 83480
    12 Tube 2 101059
    13 Tube 2 92076
    14 Tube 2 104002
    15 Tube 2 110584
    1 Tube 3 88824
    2 Tube 3 89366
    3 Tube 3 75659
    4 Tube 3 71555
    5 Tube 3 106635
    6 Tube 3 88436
    7 Tube 3 87043
    8 Tube 3 77827
    9 Tube 3 92463
    10 Tube 3 80460
    11 Tube 3 83093
    12 Tube 3 101988
    13 Tube 3 92231
    14 Tube 3 102531
    15 Tube 3 110120
    1 Tube 4 88127
    2 Tube 4 88746
    3 Tube 4 75814
    4 Tube 4 71012
    5 Tube 4 106712
    6 Tube 4 88669
    7 Tube 4 86423
    8 Tube 4 78911
    9 Tube 4 97962
    10 Tube 4 80228
    11 Tube 4 85107
    12 Tube 4 102376
    13 Tube 4 91069
    14 Tube 4 101446
    15 Tube 4 108958
    Merci d’avance

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.