24  Reproductibilité, confidentialité et éthique

ImportantQuestion de départ

Une analyse est-elle vraiment reproductible si le code fonctionne, mais que personne ne sait d’où viennent les données, quelles décisions ont été prises, ni ce qui peut être partagé sans exposer les personnes ?

24.1 Objectifs d’apprentissage

À la fin de ce chapitre, vous saurez :

  • distinguer reproductibilité computationnelle, traçabilité analytique, provenance et ouverture ;
  • organiser un projet pour pouvoir le reconstruire depuis les sources autorisées ;
  • réduire les opérations manuelles sans cacher les décisions substantives ;
  • figer les dépendances logicielles avec {renv} ;
  • versionner le code avec Git sans exposer données confidentielles ni secrets ;
  • documenter les transformations, les paramètres et les versions de sources ;
  • distinguer pseudonymisation et anonymisation ;
  • raisonner en termes de minimisation et de risque de réidentification ;
  • contrôler également les risques contenus dans les sorties ;
  • choisir une stratégie de partage graduée : code, métadonnées, données synthétiques, données anonymisées ou accès contrôlé.

24.2 Reproductible ne signifie ni public ni automatique

Quatre dimensions sont utiles à distinguer.

Dimension Question
Reproductibilité computationnelle avec les mêmes données et le même environnement, retrouve-t-on les mêmes résultats ?
Traçabilité analytique peut-on expliquer comment les sources sont devenues le fichier d’analyse ?
Provenance sait-on quelle version de la source, du questionnaire, des poids et des métadonnées a été utilisée ?
Ouverture / partage quels objets peuvent être communiqués, à qui et sous quelles conditions ?

Un projet confidentiel peut être très reproductible dans un environnement sécurisé. À l’inverse, un dépôt public contenant des fichiers sans dictionnaire ni chaîne de transformation peut être très ouvert mais difficilement reproductible.

NotePrincipe du livre

La science ouverte ne signifie pas « tout mettre en ligne ». Elle consiste notamment à rendre accessibles les objets qui peuvent l’être, tout en respectant les droits des personnes, les règles du producteur de données, les engagements de collecte et les contraintes institutionnelles.

24.3 La question-test : peut-on reconstruire plutôt que réparer ?

Une architecture simple suffit souvent :

projet/
├── README.md
├── projet.Rproj
├── renv.lock
├── data/
│   ├── raw/          # sources inchangées
│   ├── derived/      # données reconstruites par script
│   └── documentation/
├── R/                # scripts et fonctions
├── outputs/          # résultats exportés
├── figures/
├── report.qmd
└── .gitignore

La question décisive est :

Si je supprime les fichiers dérivés, tableaux et figures, puis-je les reconstruire à partir des sources autorisées et du code ?

Si la réponse est non, une partie de l’analyse dépend probablement d’une manipulation manuelle, d’un objet caché ou d’une décision non documentée.

24.4 Le fichier brut doit être une source, pas un brouillon

data/raw/ devrait idéalement contenir des copies de travail inchangées des sources autorisées. Nettoyer « directement dans Excel » puis enregistrer par-dessus le fichier d’origine rend les transformations difficiles à auditer.

Une règle simple est :

  1. conserver la source ;
  2. lire la source par code ;
  3. produire un fichier dérivé ;
  4. pouvoir supprimer ce dérivé et le reconstruire.

Cette règle ne résout pas tous les problèmes de provenance, mais elle élimine une grande partie des opérations invisibles.

24.5 Automatiser sans rendre les décisions opaques

Une fonction peut réduire la répétition. Elle ne doit pas effacer la signification des recodages.

Afficher le code R
recoder_9899 <- function(x) {
  dplyr::case_when(
    x %in% c(98, 99) ~ NA_real_,
    TRUE ~ as.numeric(x)
  )
}

Testons-la sur un cas minimal :

Afficher le code R
x_test <- c(1, 2, 98, 99, NA)

tibble::tibble(
  Valeur = x_test,
  Après = recoder_9899(x_test)
) |>
  knitr::kable()
Valeur Après
1 1
2 2
98 NA
99 NA
NA NA
AvertissementUne fonction ne doit pas cacher le sens

Une fonction générique qui applique silencieusement la même règle à vingt variables peut être moins reproductible qu’un code légèrement plus long mais accompagné du dictionnaire qui justifie chaque traitement. Factoriser le code est utile lorsque la logique reste visible.

24.6 Figer l’environnement logiciel avec {renv}

Un script correct aujourd’hui peut changer de comportement si les versions de packages évoluent. {renv} crée un environnement de projet et enregistre les dépendances dans renv.lock (Ushey et Wickham 2026).

Afficher le code R
# À exécuter une fois dans un nouveau projet
# renv::init()

# Lorsque l'environnement est stabilisé
# renv::snapshot()

# Sur une autre machine
# renv::restore()

Le lockfile n’est pas une sauvegarde des données ni de R lui-même. Il documente principalement les packages R et leurs versions. Pour une reproduction à long terme, il est utile de noter également la version de R, de Quarto et, lorsque pertinent, du système ou des dépendances externes.

24.7 Git : versionner l’histoire du code sans versionner ce qui doit rester privé

Git est particulièrement utile pour :

  • relier une version de code à une version de manuscrit ;
  • comprendre quand une décision a été introduite ;
  • comparer deux spécifications ;
  • travailler en équipe ;
  • revenir à un état antérieur.

Mais un secret ou une donnée personnelle commité puis supprimé peut rester dans l’historique.

24.7.1 Préparer .gitignore avant le premier commit

# Environnement local
.Rhistory
.RData
.Rproj.user/

# Rendu Quarto
_book/
.quarto/
_freeze/

# Données confidentielles locales
data/private/
data/raw_confidential/

# Secrets
.env
*.key
AvertissementUn dépôt Git public n’est pas un espace de stockage sécurisé

Les règles de versionnage et d’accès doivent être définies avant d’introduire des microdonnées, des clés, des jetons ou des tables de correspondance. « Je supprimerai le fichier avant de publier » n’est pas une stratégie de sécurité fiable.

24.8 Quarto : réduire les ruptures entre calcul et rédaction

Quarto associe code, texte, tableaux et figures (Posit Software, PBC 2026). Cela réduit les copier-coller manuels et permet à une modification de données ou de modèle de mettre à jour le résultat affiché.

La condition importante est que le document puisse être rendu depuis une session propre.

Afficher le code R
tibble::tibble(
  Élément = c("R", "survey", "dplyr", "ggplot2", "gtsummary"),
  Version = c(
    paste(R.version$major, R.version$minor, sep = "."),
    as.character(utils::packageVersion("survey")),
    as.character(utils::packageVersion("dplyr")),
    as.character(utils::packageVersion("ggplot2")),
    if (requireNamespace("gtsummary", quietly = TRUE)) as.character(utils::packageVersion("gtsummary")) else "non installé"
  )
) |>
  knitr::kable()
Élément Version
R 4.4.1
survey 4.5
dplyr 1.2.1
ggplot2 4.0.2
gtsummary 2.5.0

Avant diffusion :

  1. redémarrer R ;
  2. reconstruire les données dérivées ;
  3. exécuter les vérifications ;
  4. rendre le projet complet ;
  5. inspecter les warnings et sorties ;
  6. archiver la version du code correspondant à la diffusion.

Une analyse qui ne fonctionne que parce qu’un objet persiste dans .GlobalEnv n’est pas reproductible.

24.9 Le code ne remplace pas les métadonnées

Le code montre comment une opération est réalisée. Il ne dit pas nécessairement :

  • ce que signifie une variable ;
  • qui appartenait au champ ;
  • quel filtre précédait une question ;
  • comment le poids a été construit ;
  • quelle version du questionnaire s’applique ;
  • pourquoi une catégorie a été regroupée ;
  • quelles restrictions de partage s’appliquent.

Un projet d’enquête devrait donc conserver, lorsque disponible :

  • questionnaire ;
  • dictionnaire de variables ;
  • documentation du plan ;
  • documentation des poids ;
  • provenance et version des fichiers ;
  • date d’extraction pour une source évolutive ;
  • journal des transformations importantes ;
  • règles de confidentialité ou d’accès.

24.10 Journaliser les décisions importantes

Une table de décisions est souvent plus utile qu’un long commentaire perdu dans un script.

Afficher le code R
journal <- tibble::tribble(
  ~date, ~objet, ~decision, ~justification,
  "2026-08-14", "age", "999 -> NA", "code spécial documenté",
  "2026-08-14", "taille_menage", "valeurs hors plage -> NA", "contrainte du questionnaire",
  "2026-08-14", "sport_regulier", "seuil >= hebdomadaire", "définition analytique annoncée"
)

knitr::kable(journal)
date objet decision justification
2026-08-14 age 999 -> NA code spécial documenté
2026-08-14 taille_menage valeurs hors plage -> NA contrainte du questionnaire
2026-08-14 sport_regulier seuil >= hebdomadaire définition analytique annoncée

Pour une équipe, on peut ajouter auteur, ticket, commit ou note méthodologique. L’objectif n’est pas la bureaucratie : il est de rendre explicites les choix qui pourraient sinon être oubliés au moment de la rédaction.

24.11 Confidentialité : raisonner en termes de risque

24.11.1 Supprimer les noms ne suffit pas

Une vraie enquête peut rester constituée de données personnelles après suppression du nom et de l’adresse. La CNIL distingue :

  • pseudonymisation : les identifiants directs sont remplacés ou séparés, mais une réidentification reste possible avec des informations supplémentaires ;
  • anonymisation : le processus doit rendre l’identification impossible en pratique de manière irréversible, au regard du contexte et des moyens raisonnablement mobilisables (CNIL 2020, 2022a).

Ainsi, remplacer nom par id = 10428 ne suffit pas à qualifier un fichier d’anonyme.

24.11.2 Les quasi-identifiants se combinent

Une combinaison peut devenir distinctive :

  • âge exact ;
  • petite commune ;
  • profession rare ;
  • composition familiale ;
  • date d’entretien ;
  • trajectoire longitudinale ;
  • modalité rare d’une opinion ou d’une pratique.

Le risque vient souvent de la combinaison, pas d’une colonne isolée.

NotePseudonymisé n’est pas anonyme

Lorsqu’une table de correspondance est nécessaire, elle doit être séparée et protégée. La pseudonymisation réduit le risque et facilite la gouvernance, mais les données restent personnelles (CNIL 2022a).

24.11.3 Minimisation : la meilleure donnée à protéger est parfois celle que l’on ne conserve pas

La minimisation consiste à traiter ce qui est adéquat, pertinent et nécessaire à la finalité. Elle intervient à plusieurs moments :

  • conception du questionnaire ;
  • transfert entre partenaires ;
  • constitution du fichier d’analyse ;
  • durée de conservation ;
  • choix des variables partagées ;
  • granularité des sorties.

Une variable « peut-être utile plus tard » n’est pas automatiquement nécessaire au projet présent.

24.11.4 Sécurité pendant la recherche

Selon le contexte, une organisation raisonnable peut inclure :

  • contrôle d’accès ;
  • stockage institutionnel approuvé ;
  • chiffrement ;
  • séparation des identifiants et données d’analyse ;
  • limitation des copies locales ;
  • journalisation des accès ;
  • durée de conservation définie ;
  • procédure d’archivage ou de destruction (CNIL 2022b).

Ce chapitre fournit des principes généraux, pas une validation juridique d’un traitement particulier. Les règles de l’institution, du producteur et du cadre réglementaire applicable priment pour un projet réel.

24.12 Ouvrir par niveaux plutôt que raisonner en tout-ou-rien

Niveau Ce qui peut être partagé Cas typique
1. Code + métadonnées scripts, protocole, dictionnaire expurgé, environnement microdonnées non partageables
2. Données synthétiques fichier artificiel reproduisant la structure du workflow enseignement, test de code
3. Données anonymisées données ayant fait l’objet d’une analyse de risque dédiée diffusion ouverte possible selon contexte
4. Accès contrôlé microdonnées détaillées sous conditions données utiles mais sensibles

Le choix peut différer entre données, code et sorties. On peut par exemple publier le code et les métadonnées tout en conservant les données sous accès contrôlé.

24.12.1 Données synthétiques : très utiles, pas automatiquement sans risque ni scientifiquement équivalentes

enqueter est entièrement synthétique et ne représente personne. Dans des projets réels, une méthode de synthèse peut en revanche être construite à partir de données sensibles. Il faut alors examiner :

  • le risque éventuel de mémorisation ou de proximité avec des cas réels ;
  • les propriétés que la synthèse conserve ou détruit ;
  • l’écart entre résultats obtenus sur données synthétiques et résultats sur données originales.

Une base synthétique est un excellent support de reproductibilité du pipeline ; elle n’est pas automatiquement une réplique substantielle des résultats confidentiels.

24.13 Les sorties peuvent divulguer de l’information

Même si le fichier brut reste protégé, un tableau ou une figure peut révéler un profil rare.

Afficher le code R
cellules <- enqueter |>
  filter(!is.na(territoire_f), !is.na(age_classe_f), !is.na(sexe_f)) |>
  count(territoire_f, age_classe_f, sexe_f, name = "n")

cellules |>
  arrange(n) |>
  slice_head(n = 10) |>
  rename(
    Territoire = territoire_f,
    `Classe d'âge` = age_classe_f,
    `Sexe / genre` = sexe_f,
    Effectif = n
  ) |>
  knitr::kable()
Territoire Classe d’âge Sexe / genre Effectif
Île-de-France 18-29 Autre / non-binaire 1
Île-de-France 60-79 Autre / non-binaire 1
Nord-Ouest 45-59 Autre / non-binaire 1
Sud-Est 30-44 Autre / non-binaire 1
Nord-Est 18-29 Autre / non-binaire 2
Sud-Ouest 18-29 Autre / non-binaire 2
Sud-Ouest 30-44 Autre / non-binaire 2
Sud-Est 45-59 Autre / non-binaire 2
Île-de-France 45-59 Autre / non-binaire 3
Nord-Ouest 18-29 Autre / non-binaire 3
Afficher le code R
ggplot(cellules, aes(x = n)) +
  geom_histogram(
    binwidth = 5,
    boundary = 0,
    fill = couleurs_enqueter[["principal"]],
    alpha = .82
  ) +
  geom_vline(
    xintercept = 10,
    linetype = 2,
    colour = couleurs_enqueter[["alerte"]]
  ) +
  labs(
    x = "Effectif non pondéré de la cellule",
    y = "Nombre de cellules",
    title = "Croiser des variables crée rapidement des sous-groupes rares",
    subtitle = "Le seuil n = 10 est un repère visuel pédagogique, pas une règle universelle",
    caption = "Données synthétiques EnquêteR."
  ) +
  theme_enqueter()

Histogramme de la taille des cellules issues du croisement du territoire, de l'âge et du sexe.

AvertissementUn seuil de cellule n’est pas une anonymisation

Le risque dépend du contenu, de la rareté du profil dans le monde extérieur, des informations auxiliaires accessibles et des règles de diffusion. Aucune valeur universelle de n ne transforme automatiquement une sortie en objet sans risque.

24.13.1 Le risque ne se limite pas à une cellule isolée

Plusieurs sorties apparemment sûres peuvent parfois être combinées. Par exemple, publier successivement :

  • un total pour un groupe ;
  • le même total après exclusion d’une catégorie ;
  • une table détaillée par territoire ;

peut permettre de déduire indirectement une petite cellule. C’est le principe général des attaques par différenciation ou par recoupement.

La revue de confidentialité doit donc porter sur l’ensemble des sorties diffusées, pas uniquement sur chaque tableau séparément.

24.14 Auditer automatiquement la reconstructibilité du projet

Afficher le code R
audit_projet <- tibble(
  Élément = c(
    "Configuration Quarto", "Bibliographie", "Données brutes",
    "Données dérivées", "Dictionnaire", "Script de reconstruction",
    "Script d'initialisation", "Style analytique"
  ),
  Chemin = c(
    "_quarto.yml", "references.bib", "data/raw/enqueter_brut.csv",
    "data/derived/enqueter_clean.csv", "data/documentation/dictionnaire_variables.xlsx",
    "R/01-construire-enqueter-clean.R", "R/04-initialiser-analyse.R",
    "R/05-style-enqueter.R"
  )
) |>
  mutate(
    Présent = if_else(file.exists(Chemin), "Oui", "Non")
  )

knitr::kable(audit_projet)
Élément Chemin Présent
Configuration Quarto _quarto.yml Oui
Bibliographie references.bib Oui
Données brutes data/raw/enqueter_brut.csv Oui
Données dérivées data/derived/enqueter_clean.csv Oui
Dictionnaire data/documentation/dictionnaire_variables.xlsx Oui
Script de reconstruction R/01-construire-enqueter-clean.R Oui
Script d’initialisation R/04-initialiser-analyse.R Oui
Style analytique R/05-style-enqueter.R Oui

Cette vérification ne prouve pas la reproductibilité scientifique. Elle rend simplement plusieurs dépendances explicites et permet d’échouer tôt lorsqu’un élément fondamental manque.

24.15 Une checklist avant diffusion

24.15.1 Données

24.15.2 Code et environnement

24.15.3 Résultats

24.15.4 Documentation

24.16 Mini-exercice

Classez les situations suivantes en « reproductibilité », « confidentialité », ou « les deux » :

  1. un script utilise C:/Users/Marie/Desktop/fichier.csv ;
  2. un dépôt public contient une table de correspondance identifiant–email ;
  3. un article ne précise pas quel poids a été utilisé ;
  4. un tableau contient une cellule de deux personnes dans une catégorie rare ;
  5. deux tableaux publiés séparément permettent de déduire une petite cellule par différence.
  1. Reproductibilité : chemin absolu non portable.
  2. Confidentialité, et aussi gouvernance du projet.
  3. Traçabilité/reproductibilité méthodologique.
  4. Confidentialité potentielle, à évaluer selon le contexte.
  5. Confidentialité : le risque naît du recoupement de sorties, même si chacune paraît acceptable isolément.

24.17 Exercice de synthèse

24.17.1 Niveau A — Appliquer

Créez un .gitignore adapté à un projet contenant data/private/, des sorties Quarto et un fichier .env. Vérifiez que les données privées ne sont pas suivies.

24.17.2 Niveau B — Choisir

Une équipe souhaite diffuser une enquête contenant âge exact, petite commune, profession détaillée et opinions politiques. Proposez au moins trois stratégies de diffusion graduée et expliquez les compromis entre utilité scientifique et risque.

24.17.3 Niveau C — Analyser

Faites l’audit d’un de vos projets selon quatre axes : reconstructibilité, provenance, confidentialité des données, confidentialité des sorties. Produisez un plan d’action priorisé en trois niveaux : critique, important, amélioration.

24.18 À retenir

  • Reproductibilité, traçabilité, provenance et ouverture sont liées mais distinctes.
  • Les données brutes doivent rester des sources ; les dérivés doivent être reconstructibles.
  • Git rend l’histoire visible mais peut aussi conserver ce qui aurait dû rester secret.
  • {renv} aide à rendre l’environnement logiciel explicite.
  • Quarto réduit les ruptures manuelles entre calcul et rédaction.
  • Un identifiant pseudonyme ne suffit pas à rendre un fichier anonyme.
  • La minimisation s’applique à la collecte, à l’analyse, à la conservation et au partage.
  • Les données synthétiques sont utiles pour partager un workflow, mais leur statut doit être évalué selon leur mode de production.
  • Les sorties agrégées peuvent créer un risque par rareté ou par recoupement.
  • Lorsque les microdonnées ne peuvent pas être ouvertes, code, métadonnées, protocoles et environnements restent souvent partageables.

24.19 Pour aller plus loin

Pour la reproductibilité technique, voir la documentation de {renv} (Ushey et Wickham 2026) et de Quarto (Posit Software, PBC 2026). Pour les données personnelles et la recherche scientifique en France, les ressources de la CNIL sur anonymisation, pseudonymisation et sécurité constituent des points de départ à consulter dans leur version à jour (CNIL 2020, 2022a, 2022b).