25  Étude de cas complète : du fichier brut au résultat

ImportantQuestion de départ

Le niveau de diplôme est-il associé à une pratique sportive au moins hebdomadaire, et que reste-t-il de ce gradient lorsque l’on compare des profils semblables en âge, sexe et état de santé ?

25.1 Pourquoi terminer par une étude de cas ?

Ce chapitre n’ajoute presque aucune nouvelle fonction. Il assemble les gestes appris dans le livre : documenter, auditer, recoder, définir le design, décrire, modéliser, prédire, tester la sensibilité et rédiger.

L’objectif n’est donc pas de produire « une belle régression ». Il est de montrer comment une question substantielle devient un résultat reproductible dont le lecteur peut comprendre la portée et les limites.

25.2 Plan d’analyse avant le code

Nous formulons cinq décisions avant d’estimer quoi que ce soit :

  1. Population visée : la population pédagogique représentée par l’enquête synthétique ;
  2. Résultat : pratiquer une activité sportive au moins une fois par semaine ;
  3. Exposition principale : niveau de diplôme en quatre catégories ;
  4. Variables d’ajustement : âge, sexe/genre et santé déclarée ;
  5. Estimand : association descriptive/ajustée, non effet causal.
NoteQuestion de recherche

Dans la population synthétique représentée par l’enquête, la probabilité déclarée d’une pratique sportive au moins hebdomadaire varie-t-elle selon le niveau de diplôme, et cette association persiste-t-elle après ajustement sur l’âge, le sexe et l’état de santé ?

25.3 Retour au questionnaire et au dictionnaire

Avant le fichier, nous devons connaître :

  • sport_freq : 0 = jamais ; 1 = moins d’une fois par mois ; 2 = 1–3 fois par mois ; 3 = une fois par semaine ; 4 = deux fois par semaine ou plus ;
  • diplome_4 : inférieur au bac, bac, bac+2, supérieur long ;
  • age : âge en années ;
  • sante : très bonne à très mauvaise ;
  • poids_final, strate, psu : informations du plan.

La variable binaire est définie par :

\[ Y_i = 1 \quad \text{si } sport\_freq_i \in \{3,4\}. \]

La dichotomisation perd de l’information ordinale. Nous la retenons parce que « au moins hebdomadaire » est un seuil substantiellement lisible, puis nous testerons cette décision dans une analyse de sensibilité.

25.4 Repartir d’une source reconstructible

Dans une session propre, le fichier analytique doit pouvoir être reconstruit avec :

source("R/01-construire-enqueter-clean.R")
source("R/04-initialiser-analyse.R")

Le second script crée les variables lisibles utilisées ici et l’objet design. Le chapitre ne dépend donc pas d’objets créés manuellement dans une ancienne session.

25.5 Audit ciblé avant analyse

Afficher le code R
audit_cas <- enqueter |>
  summarise(
    `N lignes` = n(),
    `Identifiants uniques` = n_distinct(id),
    `Sport manquant` = sum(is.na(sport_regulier)),
    `Diplôme manquant` = sum(is.na(diplome_4)),
    `Âge manquant` = sum(is.na(age)),
    `Sexe manquant` = sum(is.na(sexe_f)),
    `Santé manquante` = sum(is.na(sante_f))
  )

knitr::kable(audit_cas)
N lignes Identifiants uniques Sport manquant Diplôme manquant Âge manquant Sexe manquant Santé manquante
3592 3592 52 64 24 32 40

Le contrôle ne cherche pas à « nettoyer encore ». Il vérifie que le fichier utilisé correspond bien aux règles déjà documentées.

25.6 Définir le design descriptif et l’échantillon des modèles

L’objet design incorpore poids, strates et PSU. Nous distinguons deux usages :

  • design_an utilise toute l’information disponible pour chaque estimation descriptive avec na.rm = TRUE ;
  • design_mod fixe une fois pour toutes les cas complets sur les variables de M3, afin que la comparaison M1 → M3 ne soit pas brouillée par un changement d’échantillon.
Afficher le code R
design_an <- design

design_mod <- subset(
  design_an,
  !is.na(sport_regulier) &
    !is.na(diplome_4) &
    !is.na(age) &
    !is.na(sexe_f) &
    !is.na(sante_f)
)

resume_design_an <- tibble::tibble(
  Usage = c("Descriptifs pondérés", "Comparaison des modèles M1–M3"),
  `N disponible` = c(nrow(design_an$variables), nrow(design_mod$variables)),
  `Degrés de liberté du plan` = c(survey::degf(design_an), survey::degf(design_mod))
)

knitr::kable(resume_design_an, align = c("l", "r", "r"))
Usage N disponible Degrés de liberté du plan
Descriptifs pondérés 3592 66
Comparaison des modèles M1–M3 3385 66
AstuceComparer des modèles à échantillon constant

Si M1 et M3 n’utilisent pas les mêmes personnes, une variation du coefficient peut provenir à la fois de l’ajout des covariables et de la sélection des cas complets. Fixer design_mod rend la comparaison plus propre. Les descriptifs, eux, n’ont pas besoin de sacrifier des observations sans raison.

25.7 Décrire le résultat avant toute régression

25.7.1 Prévalence globale

Afficher le code R
prev_sport <- survey::svymean(
  ~sport_regulier,
  design_an,
  na.rm = TRUE
)

prev_sport_ci <- confint(prev_sport)

La prévalence pondérée estimée est de 31,9%, avec un IC à 95 % de 30,3% à 33,5%.

25.7.2 Gradient selon le diplôme

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

prev_diplome_df <- svyby_ci_df(prev_diplome, "sport_regulier")
Afficher le code R
ggplot(prev_diplome_df, aes(x = diplome_4, y = estimation)) +
  geom_errorbar(
    aes(ymin = bas, ymax = haut),
    width = 0.12, linewidth = 0.8,
    colour = couleurs_enqueter[["gris"]]
  ) +
  geom_point(size = 3.2, colour = couleurs_enqueter[["principal"]]) +
  scale_y_continuous(
    labels = scales::percent_format(accuracy = 1),
    limits = c(0, 0.60)
  ) +
  labs(
    x = "Niveau de diplôme",
    y = "Pratique sportive au moins hebdomadaire",
    title = "Un gradient scolaire très net apparaît avant ajustement",
    subtitle = "Estimations pondérées et intervalles de confiance à 95 %",
    caption = "Données entièrement synthétiques EnquêteR."
  ) +
  theme_enqueter()

La proportion pondérée pratiquant un sport au moins une fois par semaine augmente régulièrement du niveau inférieur au bac au supérieur long.

Entre les deux extrêmes du diplôme, la proportion passe d’environ 19,9% à 50,3%, soit un écart d’environ 30,4% points.

25.8 Comprendre la composition des groupes

Un gradient brut peut en partie refléter des différences de composition. Les groupes de diplôme n’ont pas exactement le même âge ni le même profil de santé.

Afficher le code R
tbl_des <- design_an |>
  gtsummary::tbl_svysummary(
    by = diplome_4,
    include = c(sport_regulier_f, age, sexe_f, sante_f, revenu_mensuel),
    statistic = list(
      gtsummary::all_continuous() ~ "{median} ({p25}–{p75})",
      gtsummary::all_categorical() ~ "{p}%"
    ),
    missing = "ifany",
    missing_text = "Manquant",
    label = list(
      sport_regulier_f ~ "Pratique sportive régulière",
      age ~ "Âge",
      sexe_f ~ "Sexe / genre",
      sante_f ~ "État de santé déclaré",
      revenu_mensuel ~ "Revenu mensuel (€)"
    )
  ) |>
  gtsummary::bold_labels()

tbl_des
Caractéristique Inférieur au bac
N = 1 6231
Bac
N = 6941
Bac+2
N = 5431
Supérieur long
N = 6681
Pratique sportive régulière



    Non 80% 66% 57% 50%
    Oui 20% 34% 43% 50%
    Manquant 24 8 8 13
Âge 49 (39–60) 46 (34–56) 42 (32–53) 41 (30–51)
    Manquant 9 7 4 5
Sexe / genre



    Homme 49% 47% 52% 48%
    Femme 50% 52% 46% 50%
    Autre / non-binaire 1,4% 1,6% 1,2% 1,7%
    Manquant 14 6 4 9
État de santé déclaré



    Très bonne 10% 13% 16% 16%
    Bonne 39% 42% 44% 46%
    Moyenne 39% 37% 32% 31%
    Mauvaise 11% 8,1% 7,0% 5,4%
    Très mauvaise 0,7% 0,4% 0,9% 0,3%
    Manquant 22 3 8 7
Revenu mensuel (€) 1 950 (1 500–2 450) 2 150 (1 650–2 650) 2 400 (1 850–2 850) 2 850 (2 300–3 300)
    Manquant 157 64 43 65
1

La table ne constitue pas une « liste de contrôles ». Elle sert à comprendre ce qui distingue les groupes avant de choisir un modèle.

NoteLecture sociologique préalable

Le diplôme est ici associé à plusieurs ressources et positions dans le cycle de vie. Dans une enquête réelle, le gradient sportif pourrait être relié à des socialisations corporelles, au temps disponible, aux ressources économiques, aux conditions de travail ou à l’accès aux équipements. Les variables présentes dans le fichier n’observent toutefois qu’une partie de ces mécanismes.

25.9 Modéliser progressivement

Nous estimons trois modèles de sondage logistiques. Le but est de suivre la transformation de l’association diplôme–sport, pas de chercher le modèle donnant le plus de p-values inférieures à 0,05.

Afficher le code R
mod1 <- survey::svyglm(
  sport_regulier ~ diplome_4,
  design = design_mod,
  family = quasibinomial()
)

mod2 <- survey::svyglm(
  sport_regulier ~ diplome_4 + age + sexe_f,
  design = design_mod,
  family = quasibinomial()
)

mod3 <- survey::svyglm(
  sport_regulier ~ diplome_4 + age + sexe_f + sante_f,
  design = design_mod,
  family = quasibinomial()
)

25.9.1 Suivre uniquement le gradient de diplôme

Afficher le code R
extraire_or_diplome <- function(modele, nom_modele) {
  termes <- grep("^diplome_4", names(stats::coef(modele)), value = TRUE)
  ci <- stats::confint(modele)[termes, , drop = FALSE]
  tibble::tibble(
    Modèle = nom_modele,
    Contraste = sub("^diplome_4", "", termes),
    OR = exp(stats::coef(modele)[termes]),
    `IC 95 %` = paste0(
      "[", fmt_num(exp(ci[, 1]), .01), " ; ",
      fmt_num(exp(ci[, 2]), .01), "]"
    )
  ) |>
    dplyr::mutate(OR = round(OR, 2))
}

tbl_progression <- dplyr::bind_rows(
  extraire_or_diplome(mod1, "M1 — diplôme"),
  extraire_or_diplome(mod2, "M2 — + âge, sexe"),
  extraire_or_diplome(mod3, "M3 — + santé")
)

knitr::kable(
  tbl_progression,
  align = c("l", "l", "r", "c"),
  col.names = c("Spécification", "Diplôme vs inférieur au bac", "OR", "IC 95 %")
)
Spécification Diplôme vs inférieur au bac OR IC 95 %
M1 — diplôme Bac 2.12 [1,69 ; 2,66]
M1 — diplôme Bac+2 2.94 [2,45 ; 3,53]
M1 — diplôme Supérieur long 3.98 [3,26 ; 4,86]
M2 — + âge, sexe Bac 1.91 [1,50 ; 2,42]
M2 — + âge, sexe Bac+2 2.37 [1,95 ; 2,89]
M2 — + âge, sexe Supérieur long 3.07 [2,50 ; 3,79]
M3 — + santé Bac 1.89 [1,48 ; 2,42]
M3 — + santé Bac+2 2.37 [1,94 ; 2,89]
M3 — + santé Supérieur long 3.06 [2,49 ; 3,76]

L’intérêt de ce tableau est de voir si le gradient s’effondre, s’atténue ou reste proche lorsque la composition des groupes est partiellement prise en compte.

25.10 Le modèle final sur l’échelle des odds ratios

Afficher le code R
tab_finale <- mod3 |>
  gtsummary::tbl_regression(
    exponentiate = TRUE,
    estimate_fun = gtsummary::label_style_ratio(digits = 2),
    pvalue_fun = gtsummary::label_style_pvalue(digits = 2),
    label = list(
      diplome_4 ~ "Niveau de diplôme",
      age ~ "Âge (par année)",
      sexe_f ~ "Sexe / genre",
      sante_f ~ "État de santé déclaré"
    )
  ) |>
  gtsummary::bold_labels()

tab_finale
Caractéristique OR 95% IC p-valeur
Niveau de diplôme


    Inférieur au bac
    Bac 1,89 1,48 – 2,42 <0,001
    Bac+2 2,37 1,94 – 2,89 <0,001
    Supérieur long 3,06 2,49 – 3,76 <0,001
Âge (par année) 0,97 0,96 – 0,97 <0,001
Sexe / genre


    Homme
    Femme 1,05 0,89 – 1,24 0,58
    Autre / non-binaire 1,59 0,78 – 3,22 0,20
État de santé déclaré


    Très bonne
    Bonne 0,65 0,50 – 0,86 0,002
    Moyenne 0,43 0,31 – 0,58 <0,001
    Mauvaise 0,24 0,15 – 0,40 <0,001
    Très mauvaise 0,10 0,01 – 0,80 0,031
Abréviations: IC = intervalle de confiance, OR = rapport de cotes

Pour faciliter le texte dynamique, extrayons quelques ordres de grandeur :

Afficher le code R
or_mod3 <- exp(coef(mod3))
ci_or_mod3 <- exp(confint(mod3))

or_sup <- unname(or_mod3["diplome_4Supérieur long"])
or_sup_ci <- ci_or_mod3["diplome_4Supérieur long", ]
or_age <- unname(or_mod3["age"])

À covariables fixées, les odds associées au diplôme supérieur long sont environ 3,06 fois celles du groupe inférieur au bac (IC95 % 2,49–3,76). L’âge est associé à une diminution des odds d’environ 3,3% par année dans cette spécification linéaire.

AvertissementUn odds ratio n’est pas une différence de probabilité

Dire « OR = 3 » ne signifie pas que la probabilité est trois fois plus grande. Pour communiquer l’ampleur substantielle du gradient, nous passons maintenant aux probabilités prédites.

25.11 Probabilités ajustées : revenir à une échelle interprétable

Nous comparons quatre profils identiques — 45 ans, femme, santé déclarée bonne — qui ne diffèrent que par le diplôme.

Afficher le code R
profils <- tibble(
  diplome_4 = factor(
    c("Inférieur au bac", "Bac", "Bac+2", "Supérieur long"),
    levels = levels(enqueter$diplome_4)
  ),
  age = 45,
  sexe_f = factor("Femme", levels = levels(enqueter$sexe_f)),
  sante_f = factor("Bonne", levels = levels(enqueter$sante_f))
)

pred <- predict(
  mod3,
  newdata = profils,
  type = "response",
  se.fit = TRUE
)

pred_ci <- ci_design(
  est = as.numeric(coef(pred)),
  se = as.numeric(SE(pred)),
  design = design_mod
)

pred_df <- profils |>
  mutate(
    prob = as.numeric(coef(pred)),
    se = as.numeric(SE(pred)),
    bas = pmax(0, pred_ci[, "bas"]),
    haut = pmin(1, pred_ci[, "haut"])
  )
Afficher le code R
ggplot(pred_df, aes(x = diplome_4, y = prob)) +
  geom_errorbar(
    aes(ymin = bas, ymax = haut),
    width = 0.12, linewidth = 0.8,
    colour = couleurs_enqueter[["gris"]]
  ) +
  geom_point(size = 3.3, colour = couleurs_enqueter[["accent"]]) +
  scale_y_continuous(
    labels = scales::percent_format(accuracy = 1),
    limits = c(0, 0.60)
  ) +
  labs(
    x = "Niveau de diplôme", y = "Probabilité prédite",
    title = "Le gradient scolaire persiste pour des profils comparables",
    subtitle = "45 ans, femme, santé déclarée bonne ; modèle pondéré",
    caption = "IC à 95 % fondés sur les degrés de liberté du plan ; données synthétiques EnquêteR."
  ) +
  theme_enqueter()

À âge, sexe et santé fixés, la probabilité prédite de sport régulier augmente du niveau inférieur au bac au supérieur long.

Pour ces profils, la probabilité prédite passe de 24,2% sous le bac à 49,4% dans le supérieur long. L’écart ajusté est donc d’environ 25,2% points.

25.12 Tester le diplôme comme terme global

Une variable à quatre modalités ne doit pas être résumée par trois tests de contraste séparés.

Afficher le code R
test_diplome <- survey::regTermTest(mod3, ~diplome_4)

tibble::tibble(
  Test = "Diplôme — contribution globale dans M3",
  `Valeur-p` = fmt_p(test_diplome$p)
) |>
  knitr::kable(align = c("l", "r"))
Test Valeur-p
Diplôme — contribution globale dans M3 < 0,001

Le test porte sur les trois coefficients du diplôme simultanément. Il répond à une question différente des contrastes catégorie par catégorie et ne dispense pas d’examiner l’ampleur du gradient.

25.13 Une lecture sociologique en trois niveaux

NoteCe que l’analyse établit

Le gradient est ordonné et substantiel : la fréquence hebdomadaire augmente à mesure que le niveau de diplôme s’élève, et cette hiérarchie reste visible quand on compare des profils identiques en âge, sexe et santé dans M3. Le résultat ne repose donc pas seulement sur le fait que les groupes de diplôme n’ont pas la même composition démographique.

NoteComment le lire sociologiquement

Un tel résultat inviterait à regarder du côté des conditions sociales de la pratique : apprentissages corporels plus ou moins précoces, rapport à la santé, horaires et pénibilité du travail, ressources économiques, proximité d’équipements ou appartenance à des réseaux où l’activité sportive est valorisée. Le modèle n’observe directement qu’une petite partie de ces dimensions. Son intérêt est de montrer que le gradient demeure après quelques comparaisons pertinentes, pas de choisir à notre place le mécanisme qui l’a produit.

AvertissementLà où l’interprétation doit s’arrêter

Le diplôme n’est pas assigné aléatoirement et l’enquête est transversale. La santé peut être antérieure à la pratique, en être une conséquence ou partager avec elle des déterminants non observés. Ajuster sur la santé n’a donc pas une signification causale univoque. Le modèle décrit une association conditionnelle ; il n’identifie pas un « effet du diplôme » sur le sport.

25.14 Analyse de sensibilité 1 — conserver l’ordinalité du sport

Le seuil hebdomadaire est substantiellement lisible, mais il écrase cinq niveaux de fréquence en deux catégories. Vérifions si le gradient scolaire subsiste quand l’ordre complet de la réponse est conservé.

Afficher le code R
design_ord <- update(
  design_mod,
  sport_ord = factor(
    sport_freq,
    levels = 0:4,
    labels = c(
      "Jamais", "Moins d'une fois/mois", "1–3 fois/mois",
      "1 fois/semaine", "2 fois/semaine ou plus"
    ),
    ordered = TRUE
  )
)

mod_ord <- survey::svyolr(
  sport_ord ~ diplome_4 + age + sexe_f + sante_f,
  design = design_ord
)

termes_ord <- grep("^diplome_4", names(stats::coef(mod_ord)), value = TRUE)
se_ord <- sqrt(diag(stats::vcov(mod_ord)))[termes_ord]
crit_ord <- stats::qt(.975, df = survey::degf(design_ord))

resume_ord <- tibble::tibble(
  Contraste = sub("^diplome_4", "", termes_ord),
  OR = exp(stats::coef(mod_ord)[termes_ord]),
  bas = exp(stats::coef(mod_ord)[termes_ord] - crit_ord * se_ord),
  haut = exp(stats::coef(mod_ord)[termes_ord] + crit_ord * se_ord)
) |>
  dplyr::transmute(
    `Diplôme vs inférieur au bac` = Contraste,
    `OR de fréquence plus élevée` = fmt_num(OR, .01),
    `IC 95 %` = paste0("[", fmt_num(bas, .01), " ; ", fmt_num(haut, .01), "]")
  )

knitr::kable(resume_ord, align = c("l", "r", "c"))
Diplôme vs inférieur au bac OR de fréquence plus élevée IC 95 %
Bac 1,85 [1,53 ; 2,22]
Bac+2 2,29 [1,93 ; 2,72]
Supérieur long 3,31 [2,74 ; 3,99]

On ne compare pas directement ces odds ratios aux OR du modèle binaire : l’estimand n’est plus le même. On vérifie plutôt si la direction et l’ordre des contrastes sont conservés quand la dichotomisation disparaît.

25.15 Analyse de sensibilité 2 — un seuil plus exigeant

Définissons maintenant la pratique « fréquente » comme deux fois par semaine ou plus.

Afficher le code R
design_strict <- update(
  design_mod,
  sport_2plus = case_when(
    sport_freq == 4 ~ 1,
    sport_freq %in% 0:3 ~ 0,
    TRUE ~ NA_real_
  )
)

mod_strict <- survey::svyglm(
  sport_2plus ~ diplome_4 + age + sexe_f + sante_f,
  design = design_strict,
  family = quasibinomial()
)
Afficher le code R
resume_seuil <- dplyr::bind_rows(
  extraire_or_diplome(mod3, "Au moins 1 fois/semaine"),
  extraire_or_diplome(mod_strict, "Au moins 2 fois/semaine")
)

knitr::kable(
  resume_seuil,
  align = c("l", "l", "r", "c"),
  col.names = c("Définition du sport", "Diplôme vs inférieur au bac", "OR", "IC 95 %")
)
Définition du sport Diplôme vs inférieur au bac OR IC 95 %
Au moins 1 fois/semaine Bac 1.89 [1,48 ; 2,42]
Au moins 1 fois/semaine Bac+2 2.37 [1,94 ; 2,89]
Au moins 1 fois/semaine Supérieur long 3.06 [2,49 ; 3,76]
Au moins 2 fois/semaine Bac 1.40 [0,94 ; 2,08]
Au moins 2 fois/semaine Bac+2 2.65 [1,91 ; 3,67]
Au moins 2 fois/semaine Supérieur long 3.63 [2,59 ; 5,08]

Si l’ordre des catégories et la direction du gradient restent similaires, le résultat paraît moins dépendant du seuil exact retenu.

25.16 Analyse de sensibilité 3 — ajouter le revenu sans changer silencieusement d’échantillon

Le revenu est une ressource plausible dans l’analyse des pratiques, mais il contient davantage de valeurs manquantes. Si l’on compare directement M3 à un modèle avec revenu, on mélange ajustement supplémentaire et perte de cas.

Nous refaisons donc les deux modèles sur le même sous-échantillon où le revenu est observé.

Afficher le code R
design_revenu <- subset(design_mod, !is.na(revenu_k))

mod3_revenu_sample <- survey::svyglm(
  sport_regulier ~ diplome_4 + age + sexe_f + sante_f,
  design = design_revenu,
  family = quasibinomial()
)

mod_revenu <- survey::svyglm(
  sport_regulier ~ diplome_4 + age + sexe_f + sante_f + revenu_k,
  design = design_revenu,
  family = quasibinomial()
)
Afficher le code R
resume_revenu <- dplyr::bind_rows(
  extraire_or_diplome(mod3_revenu_sample, "Même échantillon — sans revenu"),
  extraire_or_diplome(mod_revenu, "Même échantillon — + revenu")
)

knitr::kable(
  resume_revenu,
  align = c("l", "l", "r", "c"),
  col.names = c("Spécification", "Diplôme vs inférieur au bac", "OR", "IC 95 %")
)
Spécification Diplôme vs inférieur au bac OR IC 95 %
Même échantillon — sans revenu Bac 1.90 [1,44 ; 2,52]
Même échantillon — sans revenu Bac+2 2.32 [1,89 ; 2,86]
Même échantillon — sans revenu Supérieur long 2.98 [2,41 ; 3,68]
Même échantillon — + revenu Bac 1.92 [1,43 ; 2,56]
Même échantillon — + revenu Bac+2 2.36 [1,90 ; 2,92]
Même échantillon — + revenu Supérieur long 3.07 [2,38 ; 3,96]

Le sous-échantillon avec revenu observé contient 3 079 observations, contre 3 385 dans l’analyse principale. Le tableau ci-dessus isole néanmoins l’effet de l’ajout du revenu à échantillon constant. La différence entre ces deux effectifs reste, elle, un résultat de données manquantes à discuter avec le chapitre 21.

25.17 Brut, pondéré, ajusté : trois objets différents

Pour rendre cette distinction explicite, résumons le parcours :

Afficher le code R
brut_diplome <- enqueter |>
  dplyr::filter(!is.na(diplome_4), !is.na(sport_regulier)) |>
  dplyr::group_by(diplome_4) |>
  dplyr::summarise(brut = mean(sport_regulier), .groups = "drop")

resume_gradient <- tibble::tibble(
  Niveau = as.character(pred_df$diplome_4),
  `Échantillon observé` = brut_diplome$brut[match(pred_df$diplome_4, brut_diplome$diplome_4)],
  `Estimation pondérée` = prev_diplome_df$estimation,
  `Probabilité ajustée` = pred_df$prob
) |>
  dplyr::mutate(dplyr::across(2:4, ~fmt_pct(.x, .1)))

knitr::kable(resume_gradient, align = c("l", "r", "r", "r"))
Niveau Échantillon observé Estimation pondérée Probabilité ajustée
Inférieur au bac 20,0% 19,9% 24,2%
Bac 34,2% 34,3% 37,7%
Bac+2 42,9% 42,5% 43,1%
Supérieur long 49,3% 50,3% 49,4%

Ces trois colonnes répondent à trois questions différentes. L’échantillon observé décrit les répondants effectivement disponibles ; l’estimation pondérée vise la population représentée par le design ; la probabilité ajustée compare des profils fixés artificiellement aux mêmes valeurs d’âge, de sexe et de santé. Les écarts entre colonnes ne sont donc pas des « corrections successives » d’un même nombre.

25.18 Rédiger le résultat final automatiquement

Le paragraphe final doit être lié aux objets calculés plutôt qu’à des valeurs recopiées à la main.

Dans les données synthétiques pondérées, 31,9% des répondants déclarent pratiquer un sport au moins une fois par semaine (IC95 % 30,3%–33,5%). La proportion estimée augmente régulièrement avec le diplôme, de 19,9% sous le bac à 50,3% dans le supérieur long. Le gradient demeure lorsque l’on compare des profils de 45 ans, de sexe féminin et déclarant une bonne santé : la probabilité prédite passe de 24,2% à 49,4%, soit un écart ajusté d’environ 25,2% points. Dans le même modèle, les odds du supérieur long sont 3,06 fois celles du groupe inférieur au bac (IC95 % 2,49–3,76). Ces résultats tiennent compte des poids, strates et PSU. Ils documentent un gradient social robuste à plusieurs spécifications dans un jeu entièrement synthétique ; ils n’identifient pas un effet causal du diplôme sur la pratique sportive.

Cet exemple de rédaction privilégie l’ordre de grandeur, l’incertitude et l’échelle de probabilité. Les valeurs-p restent disponibles dans les objets d’analyse, mais elles ne structurent pas le récit du résultat.

25.19 Du chapitre au rapport de recherche

Un rapport autonome peut séparer préparation, analyse et communication :

analysis/
├── 01-preparer.R
├── 02-analyser.R
├── 03-figures.R
├── rapport.qmd
└── outputs/

Avant diffusion : redémarrer R, reconstruire les données, rendre le rapport complet, vérifier warnings, effectifs analytiques, notes de tableaux et légendes.

25.20 Le workflow complet d’EnquêteR

Question scientifique
        ↓
Questionnaire + documentation
        ↓
Fichier brut immuable
        ↓
Import + labels + types
        ↓
Diagnostic des anomalies et des manquants
        ↓
Recodages documentés
        ↓
Plan d'enquête + poids
        ↓
Description pondérée
        ↓
Incertitude + tests
        ↓
Modèle adapté
        ↓
Prédictions sur une échelle interprétable
        ↓
Analyses de sensibilité
        ↓
Tableau + figure + texte
        ↓
Rapport reproductible

La compétence centrale n’est pas de connaître le plus de fonctions. Elle est de maintenir la cohérence entre question, mesure, population, design, méthode et conclusion.

25.21 Exercice final — Niveau A : reproduire

Reproduisez l’étude de cas dans un nouveau document Quarto. Le rendu doit repartir du fichier dérivé, recréer le design, produire les estimations descriptives, le tableau gtsummary, les trois modèles et la figure de probabilités ajustées.

25.22 Exercice final — Niveau B : modifier une décision

Changez le seuil de pratique régulière pour « deux fois par semaine ou plus ». Comparez prévalence, OR, probabilités prédites et intervalles. Expliquez ce qui change parce que la définition du résultat devient plus restrictive.

25.23 Exercice final — Niveau C : conduire votre propre analyse

Formulez une question nouvelle avec enqueter. Votre rapport de quatre pages hors code repliable doit contenir :

  1. question et population visée ;
  2. opérationnalisation et univers ;
  3. audit ciblé ;
  4. design ;
  5. au moins deux statistiques descriptives pondérées ;
  6. une figure avec incertitude lorsque pertinente ;
  7. un modèle justifié ;
  8. une restitution en probabilités ou effets substantiels lorsque cela améliore la lecture ;
  9. une analyse de sensibilité ;
  10. un tableau final ;
  11. un paragraphe de résultats de 150 à 250 mots ;
  12. trois limites, dont au moins une liée au dispositif d’enquête.

25.23.1 Barème indicatif sur 20

Élément Points
Question et opérationnalisation 2
Documentation / univers 2
Nettoyage et vérifications 2
Prise en compte du design 3
Description et figure 2
Modèle et justification 3
Interprétation substantielle 3
Sensibilité / limites 2
Reproductibilité du rendu 1

Une excellente copie ne se reconnaît pas à la sophistication du modèle. Elle rend les choix visibles, conserve le bon univers, prend le design au sérieux, privilégie des ordres de grandeur et de l’incertitude, distingue résultat statistique et interprétation sociologique, et refuse les conclusions causales que le dispositif ne permet pas.

25.24 À retenir

  • La question et la documentation précèdent le modèle.
  • Le design doit être intégré dès la description.
  • Le gradient brut et le gradient ajusté sont deux objets distincts.
  • Les odds ratios gagnent à être complétés par des probabilités prédites.
  • Une interprétation sociologique propose des mécanismes plausibles sans les confondre avec des mécanismes démontrés.
  • Les analyses de sensibilité testent la dépendance du résultat à des décisions raisonnables.
  • Tableau, figure et texte doivent dériver du même workflow reproductible.

25.25 Conclusion générale

Analyser des données d’enquête avec R ne consiste pas à faire défiler un catalogue de commandes. C’est construire une chaîne de raisonnement : ce que le questionnaire mesure, qui le dispositif représente, ce que le plan permet d’estimer, ce que le modèle conditionne et ce que l’on peut raisonnablement affirmer.

R et RStudio rendent cette chaîne programmable, inspectable et reproductible. Ils ne remplacent ni la connaissance de l’enquête ni le raisonnement statistique et sociologique. C’est cette articulation — question, données, design, code et interprétation — qui constitue le fil directeur d’EnquêteR.