Annexe A — Aide-mémoire R pour l’analyse d’enquête

Cette annexe regroupe les opérations les plus courantes du livre. Elle sert de mémo, pas de substitut aux chapitres méthodologiques : une fonction correcte appliquée au mauvais univers ou au mauvais design reste une mauvaise analyse.

A.1 Démarrer une session

Afficher le code R
library(tidyverse)
library(haven)
library(labelled)
library(survey)
library(gtsummary)

Pour savoir d’où vient une fonction :

survey::svymean
?survey::svymean

A.2 Importer

Besoin Fonction
CSV séparé par virgules readr::read_csv()
CSV séparé par ; readr::read_csv2()
Fichier texte avec séparateur choisi readr::read_delim()
Excel readxl::read_excel()
SPSS haven::read_sav()
Stata haven::read_dta()
SAS haven::read_sas()
RDS readRDS()
data <- readr::read_csv(
  "data/raw/enqueter_brut.csv",
  show_col_types = FALSE
)

A.3 Inspecter un fichier

dim(data)
nrow(data)
ncol(data)
names(data)
dplyr::glimpse(data)
summary(data)
head(data)

A.3.1 Identifiants et doublons

dplyr::n_distinct(data$id)

data %>%
  count(id) %>%
  filter(n > 1)

A.3.2 Valeurs uniques

sort(unique(data$sexe))
count(data, sexe)

A.3.3 Labels

labelled::look_for(data)
labelled::var_label(data$sexe)
haven::as_factor(data$sexe)

A.4 Diagnostiquer les valeurs manquantes

sum(is.na(data$revenu_mensuel))
mean(is.na(data$revenu_mensuel))

Plusieurs variables :

data %>%
  summarise(
    across(
      everything(),
      ~ mean(is.na(.x))
    )
  ) %>%
  pivot_longer(
    everything(),
    names_to = "variable",
    values_to = "taux_na"
  ) %>%
  arrange(desc(taux_na))

A.5 Sélectionner, filtrer, trier

data %>%
  select(id, age, sexe)

data %>%
  filter(age >= 18, age <= 79)

data %>%
  arrange(desc(age))

Retirer des colonnes :

data %>%
  select(-c(variable_a, variable_b))

A.6 Créer ou modifier des variables

data <- data %>%
  mutate(age_centre = age - mean(age, na.rm = TRUE))

A.6.1 case_when()

data <- data %>%
  mutate(
    sport_regulier = case_when(
      sport_freq %in% c(3, 4) ~ 1,
      sport_freq %in% c(0, 1, 2) ~ 0,
      TRUE ~ NA_real_
    )
  )

A.6.2 Classes

data <- data %>%
  mutate(
    age_classe = cut(
      age,
      breaks = c(18, 30, 45, 60, 80),
      right = FALSE,
      labels = c("18-29", "30-44", "45-59", "60-79")
    )
  )

A.7 Facteurs

data <- data %>%
  mutate(
    sexe_f = factor(
      sexe,
      levels = c(1, 2, 3),
      labels = c("Homme", "Femme", "Autre/non-binaire")
    )
  )

Changer la référence :

data$sexe_f <- relevel(data$sexe_f, ref = "Femme")

Regrouper des niveaux :

forcats::fct_collapse(
  data$diplome_f,
  "Inférieur au bac" = c("Sans diplôme", "Brevet/CEP", "CAP/BEP")
)

A.8 Résumer avec {dplyr}

data %>%
  summarise(
    n = n(),
    moyenne = mean(age, na.rm = TRUE),
    mediane = median(age, na.rm = TRUE),
    ecart_type = sd(age, na.rm = TRUE)
  )

Par groupe :

data %>%
  group_by(sexe_f) %>%
  summarise(
    age_moyen = mean(age, na.rm = TRUE),
    n = n(),
    .groups = "drop"
  )

A.9 Créer un design d’enquête

design <- survey::svydesign(
  ids = ~psu,
  strata = ~strate,
  weights = ~poids_final,
  data = data,
  nest = TRUE
)

Sous-population :

design_emploi <- subset(
  design,
  statut_emploi == 1
)
AvertissementSous-population

Préférez subset(design, ...) lorsque vous analysez un domaine d’une enquête complexe plutôt que de supprimer les observations du fichier avant d’avoir construit le design.

A.10 Décrire avec le design

A.10.1 Moyenne

survey::svymean(~age, design, na.rm = TRUE)

A.10.2 Quantiles

survey::svyquantile(
  ~age,
  design,
  quantiles = c(.25, .5, .75),
  na.rm = TRUE,
  ci = TRUE
)

A.10.3 Proportion d’un indicateur 0/1

survey::svymean(
  ~sport_regulier,
  design,
  na.rm = TRUE
)

A.10.4 Tableau pondéré

survey::svytable(~sexe_f, design)

A.10.5 Statistique par groupe

survey::svyby(
  ~satisfaction_vie,
  ~sexe_f,
  design,
  survey::svymean,
  na.rm = TRUE,
  vartype = c("se", "ci")
)

A.11 Intervalles de confiance

est <- svymean(~age, design, na.rm = TRUE)
confint(est)

Proportion :

svyciprop(
  ~I(sport_regulier == 1),
  design,
  method = "logit",
  na.rm = TRUE
)

A.12 Tests

A.12.1 Qualitative × qualitative

svychisq(
  ~sexe_f + sport_regulier,
  design,
  statistic = "F"
)

A.12.2 Moyenne entre deux groupes

svyttest(
  satisfaction_vie ~ sexe_f,
  design
)

A.12.3 Test global d’un terme dans un modèle

regTermTest(modele, ~diplome_4)

A.13 Régression linéaire

mod_lin <- svyglm(
  satisfaction_vie ~ age + sexe_f + diplome_4,
  design = design
)

summary(mod_lin)

A.14 Régression logistique

mod_log <- svyglm(
  sport_regulier ~ age + sexe_f + diplome_4,
  design = design,
  family = quasibinomial()
)

Odds ratios :

exp(coef(mod_log))
exp(confint(mod_log))

A.15 Régression ordinale

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

A.16 Comptage

mod_count <- svyglm(
  livres_12m ~ age + sexe_f + diplome_4,
  design = design,
  family = quasipoisson(link = "log")
)

A.17 Prédire

nouveau <- data.frame(
  age = 45,
  sexe_f = factor("Femme", levels = levels(data$sexe_f)),
  diplome_4 = factor("Bac", levels = levels(data$diplome_4))
)

predict(
  mod_log,
  newdata = nouveau,
  type = "response",
  se.fit = TRUE
)

A.18 Imputation multiple

library(mice)

imp <- mice(
  data_imp,
  m = 20,
  maxit = 20,
  seed = 2026,
  printFlag = FALSE
)

fit <- with(
  imp,
  lm(y ~ x1 + x2)
)

pool(fit)

A.19 Panel

Format long :

panel_long %>%
  arrange(id, vague)

Effet fixe individuel :

plm::plm(
  satisfaction_vie ~ revenu_mensuel,
  data = plm::pdata.frame(panel_long, index = c("id", "vague")),
  model = "within"
)

Modèle mixte :

lme4::lmer(
  satisfaction_vie ~ vague + revenu_mensuel + (1 | id),
  data = panel_long
)

A.20 Tableaux de publication

A.20.1 Descriptif non pondéré

data %>%
  select(age, sexe_f, diplome_4) %>%
  gtsummary::tbl_summary()

A.20.2 Descriptif pondéré

design %>%
  gtsummary::tbl_svysummary(
    include = c(age, sexe_f, diplome_4)
  )

A.20.3 Régression

gtsummary::tbl_regression(
  mod_log,
  exponentiate = TRUE
)

A.21 Graphiques

A.21.1 Catégorielle

ggplot(data, aes(x = sexe_f)) +
  geom_bar()

A.21.2 Quantitative

ggplot(data, aes(x = age)) +
  geom_histogram(binwidth = 5)

A.21.3 Comparaison

ggplot(data, aes(x = diplome_4, y = satisfaction_vie)) +
  geom_boxplot()

A.21.4 Estimation pondérée avec IC

Calculez d’abord les estimations avec svyby(), puis tracez le tableau agrégé avec geom_point() et geom_errorbar().

A.22 Sauvegarder

readr::write_csv(data, "data/derived/fichier.csv")
saveRDS(data, "data/derived/fichier.rds")
ggsave("figures/figure1.png", width = 8, height = 5)

A.23 Vérifications finales

stopifnot(n_distinct(data$id) == nrow(data))
stopifnot(all(data$age >= 18 & data$age <= 79, na.rm = TRUE))
stopifnot(all(data$sport_regulier %in% c(0, 1, NA)))

A.24 Lire une erreur

  1. Lire le message complet.
  2. Identifier la première fonction appelée dans votre code.
  3. Vérifier names(), class() et str() des objets concernés.
  4. Reproduire l’erreur sur un petit objet.
  5. Utiliser ?fonction.
  6. Éviter de modifier cinq choses à la fois.

A.25 Le mémo le plus important

Comprendre la question
       ↓
Vérifier la documentation
       ↓
Contrôler l'univers et les types
       ↓
Construire le design
       ↓
Décrire avant de modéliser
       ↓
Quantifier l'incertitude
       ↓
Interpréter sans dépasser les données