16  Tester une hypothèse sans perdre le sens substantiel

ImportantQuestion de départ

Une différence observée est-elle compatible avec la variabilité d’échantillonnage, et comment éviter qu’une valeur-p remplace l’analyse de l’amplitude du résultat ?

16.1 Objectifs d’apprentissage

À la fin de ce chapitre, vous saurez :

  • formuler une hypothèse nulle et une hypothèse alternative ;
  • interpréter une valeur-p sans la confondre avec la probabilité que l’hypothèse nulle soit vraie ;
  • choisir un test adapté à la nature de la variable et au plan d’enquête ;
  • distinguer test global, contraste particulier et estimation d’amplitude ;
  • articuler estimation, IC, valeur-p et importance substantielle ;
  • utiliser add_p() lorsque le test répond réellement à la question du tableau ;
  • gérer avec prudence seuils conventionnels, exploration et multiplicité.

16.2 Une valeur-p répond à une question étroite

Sous l’hypothèse nulle et les hypothèses du test, la valeur-p mesure à quel point une statistique au moins aussi extrême que celle observée serait inhabituelle.

Elle ne mesure pas :

  • la probabilité que \(H_0\) soit vraie ;
  • la probabilité que l’étude soit répliquée ;
  • la taille de l’effet ;
  • la pertinence sociale de la différence ;
  • la plausibilité d’un mécanisme causal.
AvertissementUne petite valeur-p n’est pas une grande différence

La valeur-p dépend à la fois de l’amplitude observée et de la précision. Un écart minuscule peut être très incompatible avec \(H_0\) dans une grande base ; un écart substantiellement important peut rester incertain dans un petit domaine.

16.3 Commencer par l’estimation : diplôme et pratique sportive

Afficher le code R
sport_diplome <- survey::svyby(
  ~sport_regulier,
  ~diplome_4,
  design,
  survey::svymean,
  na.rm = TRUE,
  vartype = c("se", "ci")
)

sport_df <- svyby_ci_df(sport_diplome, "sport_regulier")

sport_df |>
  transmute(
    `Niveau de diplôme` = diplome_4,
    `Sport régulier` = fmt_pct(estimation, .1),
    `IC 95 %` = paste0(fmt_pct(bas, .1), " – ", fmt_pct(haut, .1))
  ) |>
  knitr::kable()
Niveau de diplôme Sport régulier IC 95 %
Inférieur au bac Inférieur au bac 19,9% 17,9% – 22,0%
Bac Bac 34,3% 30,4% – 38,1%
Bac+2 Bac+2 42,5% 39,1% – 46,0%
Supérieur long Supérieur long 50,3% 46,1% – 54,4%

Les estimations montrent déjà la structure du résultat. Calculons maintenant le test global d’association adapté au plan :

Afficher le code R
test_sport <- survey::svychisq(
  ~diplome_4 + sport_regulier_f,
  design,
  statistic = "F"
)

p_low <- sport_df$estimation[sport_df$diplome_4 == "Inférieur au bac"]
p_high <- sport_df$estimation[sport_df$diplome_4 == "Supérieur long"]
diff_sport <- p_high - p_low
p_test_sport <- test_sport$p.value

tibble::tibble(
  `Écart extrêmes scolaires` = fmt_pp(diff_sport, .1),
  `Valeur-p globale` = fmt_p(p_test_sport)
) |>
  knitr::kable()
Écart extrêmes scolaires Valeur-p globale
30,4 points < 0,001

L’information substantive principale est ici l’écart d’environ 30,4 points entre les deux extrêmes scolaires. La valeur-p globale (< 0,001) indique ensuite dans quelle mesure la table observée est compatible avec l’hypothèse d’absence d’association, sous le design et le test retenus.

NoteLecture sociologique

Le résultat central n’est pas « le test est significatif », mais l’existence d’un gradient scolaire de forte amplitude dans le jeu pédagogique. Dans une enquête réelle, l’étape suivante consisterait à demander dans quelle mesure ce gradient reflète ressources, santé, cycle de vie, contraintes temporelles, offre locale ou autres mécanismes. Le test ne choisit pas entre ces explications.

16.4 Test global et contrastes particuliers ne sont pas interchangeables

Une variable à quatre modalités génère plusieurs comparaisons. Un test global répond à :

Existe-t-il des différences quelque part entre les modalités ?

Un contraste particulier répond à :

Quelle différence oppose précisément ces deux modalités ?

Pour la satisfaction de vie, ajustons un modèle simple puis testons le terme diplôme dans son ensemble.

Afficher le code R
mod_sat_diplome <- survey::svyglm(
  satisfaction_vie ~ diplome_4,
  design = design
)

test_sat_global <- survey::regTermTest(mod_sat_diplome, ~diplome_4)

sat_diplome <- survey::svyby(
  ~satisfaction_vie,
  ~diplome_4,
  design,
  survey::svymean,
  na.rm = TRUE,
  vartype = "ci"
)

sat_df <- svyby_ci_df(sat_diplome, "satisfaction_vie")

sat_df |>
  transmute(
    `Niveau de diplôme` = diplome_4,
    `Satisfaction moyenne` = fmt_num(estimation, .2),
    `IC 95 %` = paste0(fmt_num(bas, .2), " – ", fmt_num(haut, .2))
  ) |>
  knitr::kable()
Niveau de diplôme Satisfaction moyenne IC 95 %
Inférieur au bac Inférieur au bac 6,6 6,6 – 6,8
Bac Bac 6,8 6,8 – 7,0
Bac+2 Bac+2 7,0 6,8 – 7,2
Supérieur long Supérieur long 7,0 7,0 – 7,2
Afficher le code R
tibble::tibble(
  Question = "Effet global du diplôme",
  `Valeur-p` = fmt_p(test_sat_global$p)
) |>
  knitr::kable()
Question Valeur-p
Effet global du diplôme < 0,001

Le tableau donne l’amplitude des écarts entre catégories ; regTermTest() répond à la question globale de savoir si le terme diplôme apporte de l’information au modèle. Les deux sorties sont complémentaires, et aucune ne remplace l’autre.

16.5 Deux groupes : estimation, différence et test

Prenons la satisfaction selon l’emploi. Une bonne restitution commence par les deux moyennes pondérées.

Afficher le code R
sat_emploi <- survey::svyby(
  ~satisfaction_vie,
  ~en_emploi,
  design,
  survey::svymean,
  na.rm = TRUE,
  vartype = c("se", "ci")
)

sat_emploi_df <- svyby_ci_df(sat_emploi, "satisfaction_vie") |>
  mutate(
    Groupe = if_else(en_emploi == 1, "En emploi", "Pas en emploi")
  )

sat_emploi_df |>
  transmute(
    Groupe,
    `Moyenne pondérée` = fmt_num(estimation, .2),
    `IC 95 %` = paste0(fmt_num(bas, .2), " – ", fmt_num(haut, .2))
  ) |>
  knitr::kable()
Groupe Moyenne pondérée IC 95 %
0 Pas en emploi 6,6 6,4 – 6,6
1 En emploi 7,0 7,0 – 7,0

Puis le test :

Afficher le code R
test_emploi <- survey::svyttest(
  satisfaction_vie ~ en_emploi,
  design
)

tibble::tibble(
  Test = "Différence de satisfaction selon l'emploi",
  `Valeur-p` = fmt_p(test_emploi$p.value)
) |>
  knitr::kable()
Test Valeur-p
Différence de satisfaction selon l’emploi < 0,001

L’unité d’origine — ici des points sur une échelle 0–10 — est souvent plus interprétable qu’une statistique de test. Le test répond à la compatibilité avec une différence nulle ; les moyennes indiquent de quelle différence il s’agit.

16.6 Les tests de rang changent la question, ils ne suppriment pas les hypothèses

Lorsque la question porte davantage sur les rangs que sur la moyenne, {survey} propose svyranktest() :

Afficher le code R
rank_emploi <- survey::svyranktest(
  satisfaction_vie ~ en_emploi,
  design,
  test = "wilcoxon"
)

tibble::tibble(
  Test = "Wilcoxon adapté au plan",
  `Valeur-p` = fmt_p(rank_emploi$p.value)
) |>
  knitr::kable()
Test Valeur-p
Wilcoxon adapté au plan < 0,001

« Non paramétrique » ne signifie pas « sans hypothèses ». La statistique, le paramètre implicite et la sensibilité aux formes de distribution changent. Il faut choisir la procédure en fonction de la question, pas comme solution automatique après avoir vu un histogramme imparfait.

16.7 Quel test pour quelle question ?

Question Exemple Outil survey de départ
association entre deux catégorielles diplôme × sport svychisq()
différence de moyenne entre deux groupes satisfaction × emploi svyttest()
test global d’un terme à plusieurs modalités diplôme dans un modèle regTermTest()
comparaison fondée sur les rangs satisfaction × emploi svyranktest()
contraste ajusté dans un modèle coefficient ou combinaison svyglm() + contraste/IC

Cette table est plus utile à retenir qu’une liste de seuils de valeurs-p.

16.8 gtsummary::add_p() : utile lorsque table et test partagent une question

Afficher le code R
design |>
  tbl_svysummary(
    by = diplome_4,
    include = c(sport_regulier, satisfaction_vie),
    statistic = list(
      sport_regulier ~ "{p}%",
      satisfaction_vie ~ "{mean} ({sd})"
    ),
    type = sport_regulier ~ "dichotomous",
    label = list(
      sport_regulier ~ "Sport au moins hebdomadaire",
      satisfaction_vie ~ "Satisfaction de vie (0–10)"
    ),
    missing = "no"
  ) |>
  add_p(
    test = list(
      sport_regulier ~ "svy.chisq.test",
      satisfaction_vie ~ "svy.kruskal.test"
    )
  ) |>
  bold_labels()
Caractéristique Inférieur au bac
N = 1 6231
Bac
N = 6941
Bac+2
N = 5431
Supérieur long
N = 6681
p-valeur2
Sport au moins hebdomadaire 20% 34% 43% 50% <0,001
Satisfaction de vie (0–10) 6,62 (1,61) 6,86 (1,54) 7,00 (1,55) 7,05 (1,56) <0,001
1
2 Pearson’s X^2: Rao & Scott adjustment; Design-based KruskalWallis test
AstuceQuand ne pas ajouter de valeur-p ?

Si le tableau est purement descriptif, si des dizaines de variables sont explorées sans hypothèse préalable, si la question porte surtout sur l’ordre de grandeur, ou si le tableau sert à documenter un échantillon plutôt qu’à tester une hypothèse, une colonne de valeurs-p peut être inutile voire trompeuse.

16.9 Taille d’effet : revenir à une quantité qui a une unité

Pour une proportion, la différence en points de pourcentage est souvent directement lisible. Pour une moyenne, la différence dans l’unité d’origine peut l’être davantage qu’un effet standardisé.

Dans notre exemple diplôme–sport, l’écart pondéré entre supérieur long et inférieur au bac est d’environ 30,4 points. Cette quantité indique immédiatement l’amplitude. La valeur-p ne possède aucune unité substantive.

Les effets standardisés peuvent être utiles pour comparer des échelles, mais ils ne doivent pas devenir un réflexe lorsque l’unité d’origine est déjà intelligible.

16.10 Seuils : ne pas fabriquer une frontière scientifique

p = 0,049 et p = 0,051 ne représentent pas deux univers opposés. Éviter :

« il existe un effet » / « il n’existe aucun effet »

uniquement à partir d’un seuil.

Préférer une phrase qui combine estimation et incertitude :

« l’écart estimé est X ; son IC est [A ; B] ; la valeur-p du test global est Y. »

Le lecteur peut alors juger l’amplitude, la précision et la force de l’incompatibilité avec \(H_0\) sans recevoir un verdict artificiellement binaire.

16.11 Multiplicité : documenter l’exploration

Si l’on teste beaucoup d’hypothèses, certaines petites valeurs-p apparaîtront par hasard. Les réponses possibles dépendent du projet :

  • pré-enregistrer ou hiérarchiser des hypothèses principales ;
  • limiter les tests aux questions effectivement posées ;
  • ajuster des valeurs-p pour une famille de tests ;
  • qualifier clairement les analyses d’exploratoires ;
  • privilégier estimations et IC plutôt qu’une chasse aux seuils.

Illustration simple avec Holm :

Afficher le code R
p_exemple <- c(.004, .018, .032, .11, .41)

tibble::tibble(
  Hypothèse = paste0("H", seq_along(p_exemple)),
  `p brute` = p_exemple,
  `p ajustée — Holm` = p.adjust(p_exemple, method = "holm")
) |>
  mutate(across(starts_with("p"), ~round(.x, 3))) |>
  knitr::kable()
Hypothèse p brute p ajustée — Holm
H1 0.004 0.020
H2 0.018 0.072
H3 0.032 0.096
H4 0.110 0.220
H5 0.410 0.410

L’ajustement n’est pas une sanction automatique : il répond à la question de savoir quelle famille d’inférences doit être protégée contre l’accumulation de faux positifs.

16.12 Mini-exercice

Une différence moyenne de 0,05 point sur une échelle 0–10 donne p < 0,001. Peut-on conclure qu’elle est importante ?

Non. La valeur-p indique une forte incompatibilité avec une différence nulle dans le cadre du test, mais 0,05 point peut rester substantiellement négligeable. Il faut lire l’amplitude et son intervalle de confiance.

16.13 Exercice de synthèse

16.13.1 Niveau A — Appliquer

Testez l’association diplôme–sport et la différence de satisfaction selon l’emploi avec les fonctions survey appropriées. Affichez toujours les estimations avant le test.

16.13.2 Niveau B — Choisir

Pour trois comparaisons du chapitre 11, formulez explicitement \(H_0\), choisissez le test et précisez la quantité substantive qui doit être présentée avant la valeur-p.

16.13.3 Niveau C — Analyser

Construisez un mini-rapport d’une demi-page comprenant : un tableau descriptif, un IC, un test global, une mesure d’amplitude et une conclusion substantive sans vocabulaire causal. Indiquez enfin si les analyses sont confirmatoires ou exploratoires.

16.14 À retenir

  • Une valeur-p est conditionnelle à \(H_0\) et aux hypothèses du test.
  • Elle ne mesure ni la probabilité de \(H_0\) ni l’importance du résultat.
  • Les descriptifs et les ordres de grandeur précèdent le test.
  • Le plan d’enquête doit être intégré aux tests lorsque l’inférence porte sur la population représentée (Lumley et al. 2026).
  • Un test global et un contraste particulier répondent à des questions différentes.
  • Les seuils ne doivent pas transformer une mesure continue en verdict scientifique.
  • La multiplicité concerne une famille d’inférences et doit être pensée en lien avec le statut exploratoire ou confirmatoire de l’analyse.

16.15 Pour aller plus loin

La partie suivante passe à l’ajustement multivarié. La régression permettra de demander si un gradient reste visible à caractéristiques observées comparables ; elle ne transformera toujours pas automatiquement une association observationnelle en effet causal.