library(rstatix)
data("PlantGrowth")
set.seed(1234)
PlantGrowth %>% sample_n_by(group, size = 1)# A tibble: 3 × 2
weight group
<dbl> <fct>
1 5.14 ctrl
2 3.83 trt1
3 5.37 trt2
Comparez 3 groupes ou plus quand la normalité échoue — rstatix à la manière moderne, base R pour la version classique — avec le post-hoc de Dunn, en direct dans votre navigateur
Apprenez à réaliser le test de Kruskal-Wallis en R, l’alternative non paramétrique à l’ANOVA à un facteur pour comparer trois groupes ou plus quand la normalité échoue. Utilisez rstatix kruskal_test() pour un résultat tidy et base R kruskal.test() pour la sortie classique, mesurez la taille d’effet avec kruskal_effsize(), puis lancez le post-hoc de Dunn (dunn_test()) pour trouver quels groupes diffèrent — avec une boîte à moustaches ggpubr qui affiche les p-values sur le graphique. Modifiez et exécutez chaque exemple en direct.
23 juin 2026
8 juillet 2026
kruskal_test() de rstatix pour un résultat tidy, ou base R kruskal.test() pour la sortie classique. Tous deux enveloppent les mêmes statistiques.dunn_test() (fondé sur les rangs, recommandé) ou Wilcoxon par paires.kruskal_effsize(), eta-carré) et représentez-la avec ggpubr::ggboxplot() + stat_pvalue_manual() — la boîte à moustaches avec les p-values sur le graphique.Vous avez trois groupes ou plus et vous voulez savoir s’ils diffèrent — la tâche classique d’une ANOVA à un facteur. Mais l’ANOVA suppose que chaque groupe suit approximativement une distribution normale. Quand cette hypothèse échoue — données asymétriques, valeurs aberrantes, petits échantillons ou scores ordinaux — le test de Kruskal-Wallis est la réponse.
Le test de Kruskal-Wallis est l’alternative non paramétrique à l’ANOVA à un facteur. Il étend le test de Wilcoxon à deux groupes à plus de deux groupes en classant ensemble toutes les observations et en demandant si les sommes des rangs diffèrent entre les groupes — il ne fait donc aucune hypothèse de normalité. C’est le test vers lequel se tourner quand les hypothèses de l’ANOVA à un facteur ne sont pas satisfaites.
Cette leçon le réalise de deux manières — le moderne et pipe-friendly rstatix kruskal_test() et le classique base-R kruskal.test() — mesure la taille d’effet à partir de la statistique H de Kruskal-Wallis, et réalise la comparaison post-hoc qui vous dit quels groupes diffèrent réellement, le tout sur les données intégrées PlantGrowth.
Utilisez-le pour comparer une variable de sortie numérique entre 3 groupes indépendants ou plus lorsqu’une ANOVA à un facteur paramétrique n’est pas sûre :
| Situation | Paramétrique (moyennes) | Non paramétrique (rangs) |
|---|---|---|
| 2 groupes | t-test | Wilcoxon / Mann-Whitney |
| 3 groupes ou plus | ANOVA à un facteur | Kruskal-Wallis |
Passez de l’ANOVA à Kruskal-Wallis quand l’hypothèse de normalité échoue — vérifiez-la avec un test de Shapiro-Wilk et un Q-Q plot (voir la leçon sur le test de normalité). Kruskal-Wallis suppose toujours que les groupes sont indépendants et ont des distributions de forme similaire ; sous ces conditions, un résultat significatif se lit comme une différence de médianes.
Vous ne le calculez jamais à la main — kruskal_test() s’en charge — mais l’idée est simple. Regroupez les \(N\) observations, classez-les de la plus petite à la plus grande, puis comparez le rang moyen dans chacun des \(k\) groupes. La statistique de test est
\[ H = \frac{12}{N(N+1)} \sum_{i=1}^{k} \frac{R_i^2}{n_i} - 3(N+1) \]
où \(R_i\) et \(n_i\) sont la somme des rangs et la taille du groupe \(i\). Sous l’hypothèse nulle (tous les groupes tirés de la même distribution), \(H\) suit une distribution du chi-deux à \(k-1\) degrés de liberté — ce qui est le df et le p que vous verrez dans la sortie. Parce qu’il utilise les rangs, les valeurs aberrantes et la non-normalité le modifient à peine.
Nous utilisons les données intégrées PlantGrowth — le weight (poids sec) de plantes cultivées sous une condition de contrôle et deux conditions de traitement différentes (ctrl, trt1, trt2), 10 plantes par groupe. La question de recherche est de savoir si le poids médian des plantes diffère entre les trois conditions. Inspectez une ligne aléatoire par groupe avec sample_n_by() :
# A tibble: 3 × 2
weight group
<dbl> <fct>
1 5.14 ctrl
2 3.83 trt1
3 5.37 trt2
R ordonne les niveaux de facteur alphabétiquement par défaut. Ici, cela donne déjà ctrl, trt1, trt2 — mais c’est une bonne pratique de définir l’ordre explicitement avec reorder_levels() pour que le groupe de contrôle arrive en premier dans chaque tableau et chaque graphique :
Avant de tester, résumez chaque groupe. Comme Kruskal-Wallis repose sur les rangs, la médiane et l’IQR sont les compagnons naturels — rstatix get_summary_stats() les donne en un seul pipe :
# A tibble: 3 × 5
group variable n median iqr
<fct> <fct> <dbl> <dbl> <dbl>
1 ctrl weight 10 5.16 0.743
2 trt1 weight 10 4.55 0.662
3 trt2 weight 10 5.44 0.467
Le poids médian baisse légèrement du contrôle à trt1, puis remonte pour trt2 — Kruskal-Wallis nous dira si ce motif est statistiquement significatif.
Représentez toujours les groupes avant de les tester. Une boîte à moustaches de weight par group montre les trois distributions côte à côte :

trt2 se situe nettement au-dessus de trt1, avec le contrôle entre les deux — l’image suggère un véritable effet de traitement. Plutôt que de supposer la normalité, nous le confirmerons avec le test de Kruskal-Wallis fondé sur les rangs.
La question : existe-t-il une différence significative entre les poids moyens des plantes dans les 3 conditions expérimentales ?
kruskal_test() est un wrapper pipe-friendly autour de la fonction base kruskal.test(). Il prend les données et une formule outcome ~ group et renvoie un tibble tidy — une ligne, tous les chiffres dont vous avez besoin, prêts à être passés dans un rapport ou un graphique :
# A tibble: 1 × 6
.y. n statistic df p method
* <chr> <int> <dbl> <int> <dbl> <chr>
1 weight 30 7.99 2 0.0184 Kruskal-Wallis
Les colonnes sont : n (nombre total d’observations), statistic (la statistique du chi-carré H), df (= groupes − 1), p (la p-value) et method. Ici la p-value est de 0.018 — inférieure à 0.05 — donc il existe une différence statistiquement significative entre les groupes de traitement : au moins un groupe diffère.
Lancez-le sur vos propres données. Chargez d’abord votre fichier — mydata <- read.csv("my-file.csv") — faites de la colonne de groupement un facteur (mydata$group <- factor(mydata$group)), puis passez-le avec vos propres noms : mydata %>% kruskal_test(outcome ~ group).
kruskal.test() calcule le même test et affiche le rapport classique :
Kruskal-Wallis rank sum test
data: weight by group
Kruskal-Wallis chi-squared = 7.9882, df = 2, p-value = 0.01842
Lisez la sortie : Kruskal-Wallis chi-squared est la statistique H, df vaut groupes − 1, et p-value est la significativité. Elle correspond exactement au résultat de rstatix — le tibble tidy et l’affichage classique sont le même test sous deux apparences.
Une p-value vous dit si les groupes diffèrent, pas de combien. Rapportez aussi la taille d’effet. Pour Kruskal-Wallis, la mesure standard est l’eta-carré fondé sur la statistique H, eta2[H] = (H − k + 1) / (n − k) — où H est la statistique de Kruskal-Wallis, k le nombre de groupes et n le nombre total d’observations [@tomczak2014]. Multipliée par 100, c’est le pourcentage de variance des rangs expliqué par le groupement. kruskal_effsize() la calcule et en qualifie l’ampleur :
# A tibble: 1 × 5
.y. n effsize method magnitude
* <chr> <int> <dbl> <chr> <ord>
1 weight 30 0.222 eta2[H] large
Les seuils d’interprétation courants sont 0.01–0.06 faible, 0.06–0.14 modéré, ≥ 0.14 grand. Ici une grande taille d’effet est détectée, eta2[H] = 0.22 — le traitement explique une part substantielle de la variation du poids des plantes.
Un test de Kruskal-Wallis significatif est un résultat omnibus — quelque chose diffère, mais nous ne savons pas encore quelles paires de groupes diffèrent. Faites-le suivre d’un test post-hoc par paires, corrigé pour les comparaisons multiples.
Un test de Kruskal-Wallis significatif est généralement suivi du test de Dunn pour identifier quels groupes diffèrent. Contrairement aux tests de Wilcoxon par paires, le test de Dunn utilise les mêmes rangs que le test de Kruskal-Wallis et ajuste aussi pour les ex æquo, il est donc cohérent en interne. rstatix dunn_test() réalise chaque paire et corrige les p-values :
# A tibble: 3 × 9
.y. group1 group2 n1 n2 statistic p p.adj p.adj.signif
* <chr> <chr> <chr> <int> <int> <dbl> <dbl> <dbl> <chr>
1 weight ctrl trt1 10 10 -1.12 0.264 0.791 ns
2 weight ctrl trt2 10 10 1.69 0.0912 0.273 ns
3 weight trt1 trt2 10 10 2.81 0.00500 0.0150 *
Lisez group1/group2 pour la paire, p.adj pour la p-value corrigée et p.adj.signif pour les étoiles de significativité. Seule la comparaison trt1-vs-trt2 est significative ; les paires contrôle-vs-traitement ne le sont pas.
Vous pouvez aussi faire suivre de tests de Wilcoxon par paires, avec des corrections pour les tests multiples. La fonction pairwise.wilcox.test() de base R le fait directement ; l’équivalent rstatix conserve la sortie tidy :
library(rstatix)
data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
reorder_levels(group, order = c("ctrl", "trt1", "trt2"))
# Base R: pairwise.wilcox.test(PlantGrowth$weight, PlantGrowth$group, p.adjust.method = "bonferroni")
PlantGrowth %>% wilcox_test(weight ~ group, p.adjust.method = "bonferroni")# A tibble: 3 × 9
.y. group1 group2 n1 n2 statistic p p.adj p.adj.signif
* <chr> <chr> <chr> <int> <int> <dbl> <dbl> <dbl> <chr>
1 weight ctrl trt1 10 10 67.5 0.199 0.597 ns
2 weight ctrl trt2 10 10 25 0.063 0.189 ns
3 weight trt1 trt2 10 10 16 0.009 0.027 *
La comparaison par paires confirme que seuls trt1 et trt2 sont significativement différents (test de Wilcoxon, p = 0.027).
Préférez le test de Dunn après Kruskal-Wallis : il repose sur les mêmes rangs que le test omnibus et ajuste pour les ex æquo, il est donc cohérent en interne. Le Wilcoxon par paires reclasse chaque paire séparément — correct, mais c’est une procédure légèrement différente.
La figure prête à publier met le résultat du test sur le graphique — le résultat omnibus de Kruskal-Wallis dans le sous-titre (get_test_label()) et la barre par paires significative via stat_pvalue_manual(), après que add_xy_position() a calculé où placer la barre. hide.ns = TRUE n’affiche que les barres significatives, donc seule la véritable différence (trt1 vs trt2) est tracée :
library(rstatix)
library(ggpubr)
data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
reorder_levels(group, order = c("ctrl", "trt1", "trt2"))
res.kruskal <- PlantGrowth %>% kruskal_test(weight ~ group)
pwc <- PlantGrowth %>%
dunn_test(weight ~ group, p.adjust.method = "bonferroni") %>%
add_xy_position(x = "group")
ggboxplot(PlantGrowth, x = "group", y = "weight",
color = "group", palette = "jco",
xlab = "Treatment", ylab = "Plant weight") +
stat_pvalue_manual(pwc, hide.ns = TRUE) +
labs(
subtitle = get_test_label(res.kruskal, detailed = TRUE),
caption = get_pwc_label(pwc)
)
C’est la figure à rapporter : la statistique H, les df et la p-value en haut, la méthode post-hoc nommée dans la légende, et l’unique paire significative (trt1 vs trt2) marquée directement sur les boîtes.
Une couche statistique rapide. Si vous n’avez besoin que de la p-value omnibus sur un graphique (sans crochets par paires), ajoutez stat_compare_means(method = "kruskal.test") à n’importe quelle boîte à moustaches ggpubr/ggplot — elle affiche la p-value de Kruskal-Wallis directement.
Une rédaction de type publication regroupe le résultat omnibus et la comparaison par paires significative dans une phrase — par exemple :
Il existait une différence statistiquement significative entre les groupes de traitement, évaluée à l’aide du test de Kruskal-Wallis, H(2) = 7.99, p = 0.018, avec une grande taille d’effet (η²[H] = 0.22). Les tests de Wilcoxon par paires ont montré que seule la différence entre les groupes trt1 et trt2 était significative (p = 0.027) ; le contrôle ne différait significativement d’aucun des deux traitements.
Rapportez la statistique H avec ses degrés de liberté, la p-value, la taille d’effet et les différences par paires significatives — pas seulement « p < 0.05 ».
Lancez le flux complet sur les données iris — la longueur des sépales diffère-t-elle entre les trois espèces ? Modifiez les colonnes ou la méthode post-hoc et relancez ; le bac à sable démarre au premier Run.
Demandez à Prova « mes groupes ne sont pas normaux — devrais-je utiliser Kruskal-Wallis plutôt que l’ANOVA, et quel test post-hoc dois-je lancer ? » — elle répond avec du code rstatix que vous pouvez exécuter sur vos propres données, puis vous aide à lire la p-value omnibus, la taille d’effet et les comparaisons par paires. The runtime is the judge. Ask Prova →
kruskal_test() / dunn_test() could not find function. Chargez d’abord rstatix — library(rstatix) — qui fournit aussi le pipe %>% utilisé dans ces exemples.
Le test omnibus est significatif mais aucune comparaison par paires ne l’est. Le test de Kruskal-Wallis peut détecter une différence globale que les tests post-hoc corrigés pour la multiplicité ne peuvent rattacher à une paire unique, surtout avec de petits groupes. Dans PlantGrowth, l’omnibus est significatif mais seul trt1-vs-trt2 survit à la correction — c’est normal. Rapportez honnêtement le résultat omnibus et les p-values par paires ajustées, et demandez-vous si vous avez la puissance nécessaire pour localiser la différence.
La colonne de groupement est traitée comme un nombre, et non comme des groupes. Si votre colonne de groupement est numérique, le test/graphique peut la traiter comme continue. Convertissez-la d’abord en facteur — mydata$group <- factor(mydata$group) — pour que R la lise comme des groupes discrets. (Dans PlantGrowth, group est déjà un facteur.)
Le test de Kruskal-Wallis est un test statistique non paramétrique qui compare trois groupes indépendants ou plus pour déterminer s’ils proviennent de la même distribution. Au lieu de comparer les moyennes, il classe ensemble toutes les observations et compare le rang moyen de chaque groupe, il ne fait donc aucune hypothèse selon laquelle les données sont distribuées normalement — ce qui en fait l’alternative fondée sur les rangs à l’ANOVA à un facteur, recommandée quand les hypothèses de l’ANOVA ne sont pas satisfaites.
« ANOVA non paramétrique » est le raccourci courant pour désigner le test de Kruskal-Wallis — le substitut fondé sur les rangs de l’ANOVA à un facteur vers lequel on se tourne quand la normalité ne peut être supposée. Il compare les rangs moyens des groupes plutôt que leurs moyennes, il ne fait donc aucune hypothèse de normalité, ce qui en fait un bon choix pour des données asymétriques, ordinales ou riches en valeurs aberrantes avec trois groupes ou plus.
L’ANOVA à un facteur compare les moyennes des groupes et suppose que les données de chaque groupe suivent approximativement une distribution normale avec des variances similaires. Le test de Kruskal-Wallis compare les rangs (en pratique les médianes) et ne fait aucune hypothèse de normalité, c’est donc le test à utiliser quand les hypothèses de l’ANOVA échouent, quand vous avez des valeurs aberrantes ou quand la variable de sortie est ordinale. Quand la normalité tient, l’ANOVA a une puissance légèrement supérieure ; sinon Kruskal-Wallis est le choix le plus sûr.
Utilisez le test de Dunn (rstatix dunn_test()). C’est le suivi recommandé car il réutilise les mêmes rangs que le test de Kruskal-Wallis et ajuste pour les valeurs ex æquo, il est donc cohérent en interne avec le test omnibus. Appliquez toujours une correction pour comparaisons multiples (p. ex. p.adjust.method = "bonferroni"). Les tests de Wilcoxon par paires (pairwise.wilcox.test()) sont une alternative acceptable mais reclassent chaque paire séparément.
Une p-value inférieure à votre seuil de signification (souvent 0.05) signifie qu’il est peu probable que les groupes proviennent de la même distribution par hasard — vous concluez donc qu’au moins un groupe diffère. Dans l’exemple PlantGrowth, p = 0.018, donc les groupes diffèrent. Elle ne vous dit pas quels groupes diffèrent (réalisez un test post-hoc pour cela) ni quelle est l’ampleur de la différence (rapportez la taille d’effet de kruskal_effsize() pour cela).
Grossièrement, oui — mais seulement sous une condition supplémentaire. Le test compare formellement les distributions des groupes. Quand les groupes ont des distributions de forme similaire (ne différant que par leur position), un résultat significatif s’interprète comme une différence de médianes. Si les formes ou les dispersions diffèrent nettement, interprétez-le plus prudemment comme une différence dans les distributions globales (dominance stochastique).
mpg) de mtcars diffèrent selon le nombre de cylindres (cyl). N’oubliez pas de faire de cyl un facteur. Le résultat est-il significatif ?Remplissez les deux blancs avec les colonnes de sortie et de groupement dans l’ordre outcome ~ group : mpg est la sortie numérique, cyl est le groupe (désormais facteur). Regardez la colonne p pour la significativité. Pour la question 2, rappelez-vous quelle hypothèse un test de normalité à p = 0,001 rejette, et quel test abandonne cette hypothèse.
Pour la question 2 : un Shapiro-Wilk p = 0,001 rejette la normalité, donc l’hypothèse centrale de l’ANOVA à un facteur paramétrique échoue. Basculez vers le test de Kruskal-Wallis, qui classe les données et ne nécessite aucune hypothèse de normalité — puis utilisez dunn_test() pour trouver quels groupes diffèrent.
Vous savez maintenant réaliser et interpréter le test de Kruskal-Wallis en R de deux manières : le tidy rstatix kruskal_test() et le classique base-R kruskal.test(). Utilisez-le comme l’ANOVA à un facteur non paramétrique quand la normalité échoue ; lisez la p-value pour le résultat omnibus (ici p = 0.018), rapportez la taille d’effet de kruskal_effsize() (η²[H] = 0.22, grande), et lancez dunn_test() pour trouver quels groupes diffèrent (seulement trt1 vs trt2) — puis mettez le tout sur une boîte à moustaches ggpubr avec les p-values sur le graphique.
Prouvez que vous savez le faire. Maîtrisez toute la série ANOVA en R — suivez votre parcours, construisez des projets et obtenez un certificat.
Passez à Pro — Prova illimité sur vos propres données et un certificat vérifiable qui atteste la compétence.
dès 15 $/mois facturé annuellement
✓ Vous êtes Pro — continuez. The runtime is the judge.
Prêt à passer à la vitesse supérieure ?
Recevez les nouvelles leçons R & Python par e-mail
Pratique, reproductible, sans spam. Désinscription à tout moment.
Double opt-in. Nous ne partageons jamais votre e-mail.
Chaque résultat de cette page a été produit par le code montré, exécuté au moment du build contre un environnement R figé — modifiez n’importe quel bloc et faites Run pour le reproduire vous-même.
@online{2026,
author = {},
title = {Test de Kruskal-Wallis en R : ANOVA à un facteur non
paramétrique},
date = {2026-06-23},
url = {https://www.datanovia.com/learn/biostatistics/anova/kruskal-wallis-test-in-r},
langid = {fr}
}