ANOVA à un facteur dans R : comparer plusieurs moyennes de groupes

Tester si trois groupes ou plus ont des moyennes différentes — rstatix à la moderne, base R pour les classiques — en direct dans votre navigateur

Apprenez à réaliser une ANOVA à un facteur dans R pour comparer les moyennes de trois groupes ou plus. Utilisez anova_test() de rstatix pour un résultat soigné assorti d’une taille d’effet, et aov() + summary() de base R pour le tableau classique — avec les vérifications des hypothèses de normalité et d’égalité des variances, les comparaisons post-hoc Tukey HSD (et Games-Howell quand les variances diffèrent), et une boîte à moustaches ggpubr qui affiche les p-values sur le graphique. Modifiez et exécutez chaque exemple en direct.

Date de publication

23 juin 2026

Modifié

17 juillet 2026

AstucePoints clés
  • Une ANOVA à un facteur compare les moyennes de trois groupes ou plus définis par un seul facteur — c’est l’extension du t-test indépendant au-delà de deux groupes.
  • Utilisez anova_test() de rstatix pour un résultat tidy (F, p et la taille d’effet ges) ou base R aov() + summary() pour le tableau classique. Les deux calculent le même F-test.
  • Le test omnibus dit seulement qu’au moins une moyenne diffère — faites suivre un résultat significatif d’un test post-hoc : tukey_hsd() (variances égales) ou games_howell_test() (inégales).
  • Vérifiez les deux hypothèses : la normalité des résidus (shapiro_test() + Q-Q plot) et l’homogénéité des variances (levene_test()). Si la normalité échoue, utilisez plutôt le test non paramétrique de Kruskal-Wallis.
  • Visualisez-la avec ggpubr::ggboxplot() + stat_pvalue_manual() — la boîte à moustaches avec les p-values de comparaison affichées sur le graphique.

Introduction

Une ANOVA à un facteur (analyse de variance) répond à une question qui revient sans cesse dans les expériences : ces différents groupes ont-ils des moyennes différentes, ou la dispersion n’est-elle que du bruit ? C’est l’extension naturelle du t-test indépendant à deux échantillons à plus de deux groupes, où les données sont réparties selon une seule variable de regroupement (le facteur).

Le test renvoie une statistique F et une p-value pour l’hypothèse omnibus — selon laquelle toutes les moyennes de groupes sont égales. Une p-value significative vous indique qu’au moins un groupe diffère, mais pas lequel ; pour cela, vous réalisez une comparaison par paires post-hoc. Cette leçon déroule tout le flux de travail de deux façons — le anova_test() moderne et adapté au pipe de rstatix et le classique aov() de base R — à l’aide des données intégrées PlantGrowth, et montre les vérifications des hypothèses qui vous indiquent si vous pouvez vous fier au F-test.

Note

Hypothèses de l’ANOVA. Nulle : les moyennes de tous les groupes sont égales. Alternative : au moins une moyenne de groupe diffère des autres. Avec exactement deux groupes, le F-test et le t-test sont équivalents.

Comment fonctionne l’ANOVA à un facteur

L’idée est simple : décomposer la variation totale du résultat en deux parties et les comparer.

  1. Variance intra-groupe (la variance résiduelle) — de combien chaque observation diffère de sa propre moyenne de groupe.
  2. Variance inter-groupes — de combien les moyennes de groupe diffèrent de la moyenne générale.
  3. La statistique F est le rapport between / within.

Un petit F (≈ 1) signifie que les groupes diffèrent à peine par rapport à leur dispersion interne ; un grand F signifie que les moyennes de groupe sont très éloignées les unes des autres comparées au bruit — la preuve qu’au moins une moyenne est réellement différente.

L’ANOVA partitionne la variation totale du résultat entre la part entre les groupes et la part à l’intérieur de ceux-ci. En notant \(y_{ij}\) l’observation \(i\) du groupe \(j\), \(\bar{y}_j\) la moyenne de ce groupe et \(\bar{y}\) la moyenne globale (générale), les sommes des carrés — totale (T), inter-groupes (B) et intra-groupes (W) — s’additionnent exactement :

\[ SS_T = SS_B + SS_W \]

\(SS_B = \sum_j n_j (\bar{y}_j - \bar{y})^2\) mesure à quel point les moyennes de groupes s’écartent de la moyenne générale, et \(SS_W = \sum_j \sum_i (y_{ij} - \bar{y}_j)^2\) mesure la dispersion des observations à l’intérieur de leur propre groupe (le bruit résiduel).

Chaque somme des carrés devient un carré moyen quand on la divise par ses degrés de liberté, \(MS = SS / df\) : avec \(k\) groupes et \(N\) observations, \(df_B = k - 1\) et \(df_W = N - k\). La statistique F est alors le rapport des deux carrés moyens :

\[ F = \frac{MS_B}{MS_W} \]

Si les groupes partagent réellement une seule moyenne, les deux carrés moyens estiment la même variance de bruit et \(F\) se situe proche de 1 ; une vraie différence entre groupes gonfle le numérateur et pousse \(F\) au-dessus de 1. (Pour PlantGrowth : \(k = 3\), \(N = 30\), donc \(df = 2\) et \(27\) — le \(F(2, 27)\) que vous voyez dans la sortie.)

Les données : trois groupes de traitement

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 moyen des plantes diffère selon les trois conditions. Inspectez une ligne aléatoire par groupe avec sample_n_by() :

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 

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 fixer l’ordre explicitement avec reorder_levels() afin que le groupe de contrôle vienne en premier dans chaque tableau et chaque graphique :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

levels(PlantGrowth$group)
[1] "ctrl" "trt1" "trt2"

Mettez des chiffres derrière le graphique avec get_summary_stats() de rstatix — les effectifs, moyennes et écarts-types par groupe que vous rapporterez avec le test :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

PlantGrowth %>%
  group_by(group) %>%
  get_summary_stats(weight, type = "mean_sd")
# A tibble: 3 × 5
  group variable     n  mean    sd
  <fct> <fct>    <dbl> <dbl> <dbl>
1 ctrl  weight      10  5.03 0.583
2 trt1  weight      10  4.66 0.794
3 trt2  weight      10  5.53 0.443

Le groupe de contrôle est en moyenne autour de 5.03, trt1 est un peu plus bas (4.66) et trt2 est le plus élevé (5.53) — les chiffres derrière la boîte à moustaches qui suit.

Regardez d’abord les données

Tracez toujours les groupes avant de les tester. Une boîte à moustaches de weight par group montre les trois distributions côte à côte :

library(ggpubr)
library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

ggboxplot(PlantGrowth, x = "group", y = "weight", fill = "group", palette = "jco",
          xlab = "Treatment", ylab = "Plant weight")

A boxplot of PlantGrowth plant weight by treatment group (ctrl, trt1, trt2). The trt2 group sits highest, trt1 lowest, with overlapping but visibly shifted distributions.

Un graphique des moyennes avec barres d’erreur rend le motif explicite — ggline() trace les moyennes de groupes reliées par une ligne, avec l’erreur standard comme bande et les points bruts dispersés par-dessus :

library(ggpubr)
library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

ggline(PlantGrowth, x = "group", y = "weight",
       add = c("mean_se", "jitter"), palette = "jco",
       xlab = "Treatment", ylab = "Plant weight")

A line plot of mean plant weight at each treatment group with standard-error bars and the jittered raw points; trt1 dips below the control and trt2 rises above it.

trt2 se situe nettement au-dessus du contrôle tandis que trt1 plonge légèrement en dessous — l’image suggère un effet de traitement réel. Confirmons-le avec le test, puis vérifions les hypothèses.

Vérifiez les hypothèses

Une ANOVA à un facteur repose sur quelques hypothèses concernant les données (au-delà d’observations indépendantes et aléatoires) : aucune valeur aberrante extrême, les résidus sont distribués normalement, et les groupes ont une variance égale. Vérifiez-les avant de croire la p-value.

Valeurs aberrantes

identify_outliers() signale les valeurs extrêmes dans chaque groupe selon la règle de la boîte à moustaches — un résultat vide signifie qu’aucune ne fausserait les moyennes de groupes :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

PlantGrowth %>%
  group_by(group) %>%
  identify_outliers(weight)
# A tibble: 2 × 4
  group weight is.outlier is.extreme
  <fct>  <dbl> <lgl>      <lgl>     
1 trt1    5.87 TRUE       FALSE     
2 trt1    6.03 TRUE       FALSE     

Il n’y avait aucune valeur aberrante extrême.

Note

Là où vous avez des valeurs aberrantes extrêmes, elles peuvent provenir d’erreurs de saisie ou de mesure, ou être des valeurs réellement inhabituelles. Vous pouvez conserver une valeur aberrante si vous ne pensez pas qu’elle changera la conclusion — comparez l’ANOVA avec et sans elle — ou réaliser une ANOVA robuste (par ex. le package WRS2) qui lui accorde un poids moindre.

Normalité des résidus — Shapiro-Wilk + Q-Q plot

L’hypothèse de normalité peut être vérifiée de deux façons : en analysant les résidus du modèle (une seule vérification pour tous les groupes ensemble — pratique avec beaucoup de groupes ou peu de points par groupe), ou par groupe (utile avec peu de groupes et beaucoup de points chacun). Nous montrons les deux.

Sur les résidus. Ajustez le modèle, extrayez les résidus, et testez-les avec Shapiro-Wilk (p > 0.05 → pas de départ de la normalité), appuyé par un Q-Q plot — les points devraient longer la ligne de référence :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

# Shapiro-Wilk on the model residuals
model <- lm(weight ~ group, data = PlantGrowth)
shapiro_test(residuals(model))
# A tibble: 1 × 3
  variable         statistic p.value
  <chr>                <dbl>   <dbl>
1 residuals(model)     0.966   0.438
library(ggpubr)
library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))
model <- lm(weight ~ group, data = PlantGrowth)

ggqqplot(residuals(model))

A Q-Q plot of the ANOVA model residuals against the normal distribution; the points fall close to the 45-degree reference line inside the shaded confidence band, indicating approximately normal residuals.

La p-value de Shapiro-Wilk est non significative (p ≈ 0.13) et les points tombent le long de la ligne — la normalité tient.

Par groupe. Avec seulement trois groupes, vous pouvez aussi tester chacun et tracer un Q-Q plot à facettes :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

PlantGrowth %>%
  group_by(group) %>%
  shapiro_test(weight)
# A tibble: 3 × 4
  group variable statistic     p
  <fct> <chr>        <dbl> <dbl>
1 ctrl  weight       0.957 0.747
2 trt1  weight       0.930 0.452
3 trt2  weight       0.941 0.564
library(ggpubr)
library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

ggqqplot(PlantGrowth, "weight", facet.by = "group")

Three Q-Q plots of plant weight, one per treatment group; within each panel the points fall approximately along the reference line, indicating normality in every group.

Les poids sont distribués normalement (p > 0.05) dans chaque groupe.

Note

Si votre taille d’échantillon est grande (n > 50), préférez le Q-Q plot : Shapiro-Wilk devient très sensible au moindre écart à la normalité quand n est grand. Et si vous avez un vrai doute sur la normalité, utilisez plutôt le test de Kruskal-Wallis non paramétrique.

Homogénéité des variances — test de Levene

L’ANOVA suppose également que les groupes partagent une variance commune. Le graphique résidus-en-fonction-des-valeurs-ajustées est la vérification visuelle — une bande de points à peu près plate et uniforme (sans forme d’entonnoir) signifie que la dispersion est constante d’un groupe à l’autre :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))
model <- aov(weight ~ group, data = PlantGrowth)

plot(model, 1)   # residuals vs fitted — a flat band = equal variance

A residuals-versus-fitted plot of the one-way ANOVA model; the residuals scatter in an even horizontal band around zero across the three fitted group means, with no funnel shape, indicating constant variance.

Appuyez-la avec le test de Levene, qui demande formellement si les variances de groupes sont égales (p > 0.05 → aucune preuve qu’elles diffèrent, ce que nous voulons). Avec rstatix, c’est un seul pipe :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

PlantGrowth %>% levene_test(weight ~ group)
# A tibble: 1 × 4
    df1   df2 statistic     p
  <int> <int>     <dbl> <dbl>
1     2    27      1.12 0.341

Un test de Levene non significatif (p > 0.05) signifie que l’égalité des variances tient, donc l’ANOVA classique (et le post-hoc Tukey) est appropriée. S’il était significatif, passez à l’ANOVA Welch (welch_anova_test()) et au test post-hoc Games-Howell, qui ne supposent pas l’égalité des variances — voir la section relâcher l’hypothèse plus bas.

Réaliser l’ANOVA à un facteur

Avec rstatix (recommandé)

anova_test() prend les données et une formule outcome ~ factor et renvoie un tibble soigné — une ligne, tous les chiffres dont vous avez besoin :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

res.aov <- PlantGrowth %>% anova_test(weight ~ group)
res.aov
ANOVA Table (type II tests)

  Effect DFn DFd     F     p p<.05   ges
1  group   2  27 4.846 0.016     * 0.264

Les colonnes sont F (la statistique), DFn/DFd (degrés de liberté), p (la p-value), p<.05 (un indicateur de signification), et ges — la taille d’effet eta-carré généralisé, la proportion de variation de weight expliquée par group. Il y a des différences significatives entre les groupes, F(2, 27) = 4.85, p = 0.016, et ges = 0.26 — le traitement explique environ 26 % de la variation du poids des plantes. En règle générale, les repères de l’eta-carré généralisé (η²) sont petit ≈ 0.01, moyen ≈ 0.06 et grand ≥ 0.14 — donc 0.26 est un effet grand.

Astuce

Lancez-la sur vos propres données. Chargez d’abord votre fichier — mydata <- read.csv("my-file.csv") — faites de la colonne de regroupement un facteur avec mydata$group <- factor(mydata$group), puis passez-la dans le pipe : mydata %>% anova_test(outcome ~ group).

Avec base R

aov() ajuste le modèle et summary() affiche le tableau classique de l’ANOVA :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

res.aov.base <- aov(weight ~ group, data = PlantGrowth)
summary(res.aov.base)
            Df Sum Sq Mean Sq F value Pr(>F)  
group        2  3.766  1.8832   4.846 0.0159 *
Residuals   27 10.492  0.3886                 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Lisez le tableau : Df sont les degrés de liberté, F value est la statistique, et Pr(>F) est la p-value (les étoiles signalent la significativité). C’est le même F et le même p que l’appel rstatix — aov() affiche simplement la présentation classique et conserve le modèle ajusté pour les diagnostics et les tests post-hoc.

Post-hoc : quels groupes diffèrent ?

Une ANOVA significative dit que certaines moyennes diffèrent — pour trouver quelles paires, lancez un test post-hoc qui corrige les comparaisons multiples.

Tukey HSD (variances égales)

tukey_hsd() compare chaque paire et ajuste les p-values (Tukey Honest Significant Differences) :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

PlantGrowth %>% tukey_hsd(weight ~ group)
# A tibble: 3 × 9
  term  group1 group2 null.value estimate conf.low conf.high  p.adj p.adj.signif
* <chr> <chr>  <chr>       <dbl>    <dbl>    <dbl>     <dbl>  <dbl> <chr>       
1 group ctrl   trt1            0   -0.371   -1.06      0.320 0.391  ns          
2 group ctrl   trt2            0    0.494   -0.197     1.19  0.198  ns          
3 group trt1   trt2            0    0.865    0.174     1.56  0.0120 *           

La sortie donne estimate (la différence entre les deux moyennes de groupes), conf.low/conf.high (l’intervalle de confiance à 95 %) et p.adj (la p-value ajustée). Seule la différence entre trt2 et trt1 est significative (p ajustée = 0.012) ; les différences contrôle-vs-traitement ne le sont pas.

L’équivalent base R prend l’objet aov() ajusté :

library(rstatix)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

res.aov.base <- aov(weight ~ group, data = PlantGrowth)
TukeyHSD(res.aov.base)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = weight ~ group, data = PlantGrowth)

$group
            diff        lwr       upr     p adj
trt1-ctrl -0.371 -1.0622161 0.3202161 0.3908711
trt2-ctrl  0.494 -0.1972161 1.1852161 0.1979960
trt2-trt1  0.865  0.1737839 1.5562161 0.0120064

Autres options de comparaison par paires

Tukey HSD n’est pas la seule approche post-hoc. La fonction pairwise.t.test() de base R réalise toutes les comparaisons par paires et vous laisse choisir directement la correction pour comparaisons multiples. Utilisez la méthode de Benjamini-Hochberg ("BH") pour contrôler le taux de fausses découvertes — la proportion attendue de faux positifs parmi les résultats significatifs — une alternative moins conservatrice que Tukey lorsque vous avez plusieurs paires :

data("PlantGrowth")

pairwise.t.test(PlantGrowth$weight, PlantGrowth$group, p.adjust.method = "BH")

    Pairwise comparisons using t tests with pooled SD 

data:  PlantGrowth$weight and PlantGrowth$group 

     ctrl  trt1 
trt1 0.194 -    
trt2 0.132 0.013

P value adjustment method: BH 

Le résultat est une matrice triangulaire de p-values ajustées, une par paire. Seule la différence entre trt2 et trt1 ressort significative (p ≈ 0.013) — la même conclusion que Tukey : les deux traitements diffèrent l’un de l’autre, mais aucun ne diffère significativement du contrôle.

Si vous utilisez déjà multcomp pour d’autres contrastes, sa fonction glht() donne les mêmes comparaisons de Tukey que TukeyHSD() à partir du modèle aov() ajusté — summary(multcomp::glht(res.aov.base, linfct = multcomp::mcp(group = "Tukey"))). Utile à savoir lorsque vous avez besoin d’hypothèses linéaires générales au-delà de l’ensemble standard des comparaisons deux à deux de Tukey.

Tracez-le avec les p-values dessus

La figure prête à publier met le résultat du test sur le graphique — l’ANOVA globale dans le sous-titre (get_test_label()) et le crochet par paire significatif via stat_pvalue_manual(), après que add_xy_position() calcule où le crochet se place. hide.ns = TRUE masque les paires non significatives de sorte que seule la vraie différence (trt1 vs trt2) soit tracée :

library(rstatix)
library(ggpubr)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

res.aov <- PlantGrowth %>% anova_test(weight ~ group)
pwc <- PlantGrowth %>%
  tukey_hsd(weight ~ group) %>%
  add_xy_position(x = "group")

ggboxplot(PlantGrowth, x = "group", y = "weight",
          xlab = "Treatment", ylab = "Plant weight") +
  stat_pvalue_manual(pwc, hide.ns = TRUE) +
  labs(
    subtitle = get_test_label(res.aov, detailed = TRUE),
    caption = get_pwc_label(pwc)
  )

A boxplot of PlantGrowth plant weight by treatment group (ctrl, trt1, trt2) with the overall ANOVA F(2,27)=4.85, p=0.016 and generalized eta-squared = 0.26 printed as a subtitle, and a significance bracket between trt1 and trt2 drawn above the boxes.

C’est la figure à rapporter : le F omnibus, les degrés de liberté, la p-value et la taille d’effet en haut, et l’unique paire significative (trt1 vs trt2) marquée directement sur les boîtes.

Rapporter le résultat

Une rédaction de type publication regroupe le résultat omnibus, la taille d’effet et les comparaisons par paires significatives en une seule phrase — par exemple :

Une ANOVA à un facteur a été réalisée pour comparer le poids des plantes entre les trois groupes de traitement — contrôle (n = 10), trt1 (n = 10) et trt2 (n = 10). Le poids des plantes différait significativement entre les groupes, F(2, 27) = 4.85, p = 0.016, η² généralisé = 0.26. Les comparaisons post-hoc Tukey ont montré que l’augmentation de trt1 (4.66 ± 0.79) à trt2 (5.53 ± 0.44) était significative (différence 0.87, IC à 95 % [0.17, 1.56], p.adj = 0.012), aucune autre paire n’étant significativement différente.

Rapportez la statistique F avec ses degrés de liberté, la p-value, la taille d’effet (ges) et les différences par paires significatives — pas seulement « p < 0.05 ».

Relâcher l’hypothèse d’égalité des variances

L’ANOVA classique à un facteur suppose des variances égales entre les groupes. Ici, le test de Levene était non significatif, donc c’est correct — mais quand l’égalité des variances échoue, l’ANOVA à un facteur de Welch (welch_anova_test()) est l’alternative qui ne l’exige pas, associée au test post-hoc Games-Howell (bâti sur la correction de Welch, sans hypothèse d’égalité des variances ni d’égalité des effectifs). La figure ci-dessous remplace les deux — notez la même recette get_test_label() / stat_pvalue_manual() :

library(rstatix)
library(ggpubr)

data("PlantGrowth")
PlantGrowth <- PlantGrowth %>%
  reorder_levels(group, order = c("ctrl", "trt1", "trt2"))

# Welch one-way ANOVA + Games-Howell post-hoc (no equal-variance assumption)
res.aov2 <- PlantGrowth %>% welch_anova_test(weight ~ group)
pwc2 <- PlantGrowth %>%
  games_howell_test(weight ~ group) %>%
  add_xy_position(x = "group", step.increase = 1)

ggboxplot(PlantGrowth, x = "group", y = "weight",
          xlab = "Treatment", ylab = "Plant weight") +
  stat_pvalue_manual(pwc2, hide.ns = TRUE) +
  labs(
    subtitle = get_test_label(res.aov2, detailed = TRUE),
    caption = get_pwc_label(pwc2)
  )

A boxplot of plant weight by treatment group with the Welch one-way ANOVA result in the subtitle and Games-Howell pairwise brackets drawn for the significant comparisons.

Astuce

Quel post-hoc ? Réalisez d’abord le test de Levene. Variances égales → Tukey HSD. Variances inégales → Games-Howell (souvent le choix par défaut le plus sûr, car il se dégrade en douceur quand les variances sont égales). Vous pouvez aussi utiliser des tests t par paires avec pool.sd = FALSE quand les variances diffèrent.

Note

Si les résidus s’éloignent fortement de la ligne, ou si le test de Levene est significatif, les données peuvent ne pas convenir à l’ANOVA classique. Utilisez l’ANOVA Welch pour des variances inégales, ou le test de Kruskal-Wallis non paramétrique quand la normalité échoue. Voir la leçon dédiée au test de normalité pour le flux de travail complet des hypothèses.

AstuceQuel test, quand ?

Laissez les hypothèses choisir le test :

  • Variances égales + résidus normaux → l’ANOVA à un facteur classique (anova_test()), avec post-hoc Tukey HSD (tukey_hsd()).
  • Variances inégales (test de Levene significatif) → ANOVA Welch (welch_anova_test()), avec post-hoc Games-Howell (games_howell_test()).
  • Résidus non normaux → le test de Kruskal-Wallis non paramétrique (kruskal_test()), avec post-hoc test de Dunn.
  • Plus d’un facteur de regroupement → passez à une ANOVA à deux facteurs ou ANOVA à trois facteurs pour tester deux ou trois facteurs et leurs interactions d’un coup.

Essayez en direct

Réalisez le flux de travail complet sur un autre jeu de données — InsectSprays (count d’insectes par type de pulvérisateur, six groupes A–F). Modifiez les colonnes, le jeu de données ou le test post-hoc et relancez ; le bac à sable démarre au premier Run.

🟢 Avec un agent IA

Demandez à Prova « J’ai un résultat numérique et une colonne de regroupement — lance la bonne ANOVA sur mes données, vérifie les hypothèses et dis-moi quels groupes diffèrent » — elle répond avec du code rstatix que vous pouvez exécuter sur vos propres données, puis vous aide à lire le F-test, la taille d’effet et le tableau post-hoc. The runtime is the judge. Demander à Prova →

Problèmes courants

anova_test() rapporte le facteur comme numérique / donne 1 degré de liberté. Votre variable de regroupement est encore numérique — l’ANOVA la traite comme un prédicteur continu (une pente de régression), et non comme plusieurs groupes. Faites-en d’abord un facteur : mydata$group <- factor(mydata$group) (dans PlantGrowth, group est déjà un facteur).

L’ANOVA est significative mais chaque paire post-hoc est non significative (ou inversement). Le F-test omnibus et les tests par paires corrigés pour la multiplicité répondent à des questions différentes ; les cas limites peuvent se contredire. Dans PlantGrowth, l’omnibus est significatif mais seule la paire trt1-vs-trt2 survit à la correction de Tukey — c’est normal. Fiez-vous aux comparaisons post-hoc pour savoir quels groupes diffèrent, et rapportez toujours la taille d’effet, pas seulement la p-value.

Le test de Levene est significatif, donc mon Tukey HSD est peut-être faux. L’égalité des variances a échoué. Relancez les comparaisons avec games_howell_test() (et rapportez un omnibus welch_anova_test()), qui ne supposent pas des variances égales.

Questions fréquentes

La façon tidy est rstatix : faites de votre colonne de regroupement un facteur, puis mydata %>% anova_test(outcome ~ group) — elle renvoie la statistique F, la p-value et une taille d’effet ges en une seule ligne. La façon base R est summary(aov(outcome ~ group, data = mydata)), qui affiche le tableau classique de l’ANOVA. Les deux calculent le même F-test.

Un t-test compare les moyennes d’exactement deux groupes ; une ANOVA à un facteur en compare trois ou plus. Lancer de nombreux t-tests à la place gonfle le taux de faux positifs, ce que l’ANOVA évite avec un seul F-test omnibus. Avec exactement deux groupes, l’ANOVA et le t-test indépendant donnent des résultats identiques (F = t²).

Si le test de Levene montre des variances égales, utilisez Tukey HSD (tukey_hsd()) — il compare toutes les paires et corrige la multiplicité. Si les variances sont inégales, utilisez Games-Howell (games_howell_test()), qui s’appuie sur la correction de Welch et ne suppose ni variances égales ni tailles de groupe égales. Ne lancez un test post-hoc qu’après une ANOVA omnibus significative.

Quatre, en réalité : les observations sont indépendantes et aléatoires, il n’y a aucune valeur aberrante extrême (identify_outliers()), les résidus sont distribués normalement (vérifiez avec shapiro_test() sur les résidus du modèle et un Q-Q plot), et les groupes ont une variance égale (vérifiez avec levene_test()). Si l’égalité des variances échoue, utilisez l’ANOVA Welch ; si la normalité échoue, utilisez le test de Kruskal-Wallis non paramétrique.

La statistique F est le rapport de la variance inter-groupes à la variance intra-groupes — à quel point les moyennes de groupes s’écartent les unes des autres par rapport au bruit à l’intérieur de chaque groupe. Une grande F signifie que les moyennes de groupes diffèrent davantage que le bruit du hasard ne pourrait l’expliquer, ce qui est une preuve qu’au moins une moyenne est réellement différente.

Pour des variances inégales, utilisez welch_anova_test() plus le test post-hoc de Games-Howell — aucun des deux ne suppose des variances égales. Pour des données non normales, utilisez le test de rangs de Kruskal-Wallis (kruskal_test()), l’alternative non paramétrique à l’ANOVA à un facteur, suivi du test de Dunn pour les comparaisons par paires.

Testez vos connaissances

  1. Exécutez-la. Dans la cellule interactive ci-dessous, réalisez une ANOVA à un facteur du weight des plantes par group dans PlantGrowth. Remplissez les blancs. Le test omnibus est-il significatif ? Quelle est la taille d’effet ges ?
  2. Conceptuel. Votre ANOVA omnibus est significative, mais vous avez trois groupes. Pourquoi ne pouvez-vous pas vous arrêter là, et que devriez-vous exécuter ensuite ?

Remplissez les deux blancs avec le résultat weight et le facteur group. Regardez la colonne p pour la signification et la colonne ges pour la taille d’effet. Pour la question 2, rappelez-vous que le F-test omnibus répond à une question différente de celle des comparaisons par paires.

library(rstatix)
data("PlantGrowth")
PlantGrowth %>% anova_test(weight ~ group)
#> F(2, 27) = 4.85, p = 0.016, ges = 0.26  → significant; treatment explains ~26% of the variation.

L’ANOVA omnibus est significative (p = 0.016) et ges = 0.26 — le groupe explique environ 26 % de la variation du poids des plantes.

Pour la question 2 : une ANOVA omnibus significative vous indique seulement qu’au moins une des trois moyennes de groupes diffère — et non lesquelles. Vous devez réaliser un test par paires post-hoc (tukey_hsd(), ou games_howell_test() si les variances sont inégales) qui corrige les comparaisons multiples pour identifier les paires spécifiques qui diffèrent (ici, seulement trt1 vs trt2).

Conclusion

Vous savez désormais réaliser et interpréter une ANOVA à un facteur dans R de deux façons : le anova_test() soigné de rstatix (avec sa taille d’effet ges) et le classique aov() + summary() de base R. Vérifiez les hypothèses — aucune valeur aberrante, normalité des résidus (shapiro_test) et égalité des variances (levene_test) — lisez le F-test omnibus, puis faites suivre un résultat significatif d’une comparaison post-hoc (tukey_hsd(), ou games_howell_test() quand les variances diffèrent). Quand les hypothèses échouent, le test de Kruskal-Wallis est le recours non paramétrique.

Leçons connexes

Cette page vous a-t-elle été utile ?

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.

Commencer gratuitement →

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

Passer à Pro →

✓ Vous êtes Pro — continuez. The runtime is the judge.

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.

Partager cette pageXLinkedInRedditHN
Note

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.

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {ANOVA à un facteur dans R : comparer plusieurs moyennes de
    groupes},
  date = {2026-06-23},
  url = {https://www.datanovia.com/learn/biostatistics/anova/anova-in-r},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“ANOVA à un facteur dans R : comparer plusieurs moyennes de groupes.” 2026. June 23. https://www.datanovia.com/learn/biostatistics/anova/anova-in-r.