Outils pour une Science Reproductible, Ouverte & Diffusable

DiplĂŽme Universitaire Public Health Data Science

Auteur·rice
Date de publication

25 mai 2026

Avant-propos et instructions

Note🎯 Objectifs pĂ©dagogiques

À la fin de ce cours vous saurez :

  1. Expliquer pourquoi la reproductibilité est essentielle en science, et identifier ses principaux obstacles.
  2. Organiser un projet d’analyse de donnĂ©es de façon Ă  ce que tout collĂšgue (y compris votre futur vous) puisse le rĂ©-exĂ©cuter de zĂ©ro.
  3. Rédiger un document dynamique complet et reproductible avec Quarto mélant narration, code et résultats.
  4. Produire des visualisations prĂȘte pour publication avec ggplot2 () ou seaborn/ matplotlib (), et les sauvegarder de maniĂšre programmatique.
  5. Auditer votre propre projet selon une check-list de reproductibilité avant de le partager.

Instructions : comment naviguer dans ce cours

Ce cours s’articule en 4 Parties (augmentĂ©es par cette introduction, ainsi qu’un rĂ©sumĂ© conclusif). Tout au long de votre session, vous rencontrerez trois types d’activitĂ©s, identifiĂ©es par les icĂŽnes ci-dessous :

IcĂŽne Type Objectif
📖 Lecture ciblĂ©e Une courte ressource externe Ă  lire (~5–10 min). Suivez les liens — ne les ignorez pas.
💡 DĂ©finition de concept IdĂ©es clĂ©s avec illustrations et exemples rĂ©solus.
đŸ§‘â€đŸ’» Exercice pratique VOUS Ă©crivez et exĂ©cutez le code vous-mĂȘme. Les blocs ne sont pas prĂ©-exĂ©cutĂ©s dans ce cas.

Choisissez R ou python , les deux langages sont prĂ©sentĂ©s dans les exercices via des onglets, mais vous n’avez besoin d’en faire qu’un seul (au choix, selon votre prĂ©fĂ©rence initiale).

Temps total nĂ©cessaire : environ ~3 heures. N’hĂ©sitez pas Ă  faire une courte pause entre chaque partie !


⚙ Configuration (avant d’entamer le cours)

Installez la derniùre version de → https://cran.r-project.org/
Installez la derniùre version de RStudio → https://posit.co/download/rstudio-desktop/

Exécuter ensuite les lignes ci-dessous dans votre console :

install.packages(c(
  "tidyverse",    # ggplot2, dplyr, readr, 

  "gapminder",    # notre jeu de données principal
  "renv",         # gestion des dépendances
  "here",         # chemins de fichiers portables
  "quarto",       # rendu des .qmd depuis R
  "knitr",        # moteur de compilation
  "sessioninfo"   # documenter votre environnement
))

VĂ©rifiez que Quarto est disponible : dans l’onglet Terminal de RStudio, tapez quarto --version.
Vous devez obtenir en retour un numĂ©ro de version si tout fonctionne correctement (par exemple ≄ 1.4).

Installez Python ≄ 3.10 → https://www.python.org/downloads/
Installez VS Code → https://code.visualstudio.com/ (avec l’extension Python)
ou utilisez JupyterLab : pip install jupyterlab

Créez et activez un environnement virtuel, puis installez les packages nécessaires en executant les lignes de code ci-dessous:

# Créer le dossier du projet et l'environnement virtuel
mkdir repro-phds && cd repro-phds
python -m venv .venv

# Activer (choisissez la ligne correspondant Ă  votre OS)
source .venv/bin/activate       # pour macOS ou Linux
 .venv\Scripts\activate         # pour Windows (PowerShell)

# Installer les bibliothĂšques Python
pip install pandas matplotlib seaborn gapminder jupyterlab quarto

Vérifiez que Quarto est bien disponible en exécutant quarto --version dans votre terminal (vous devez obtenir en retour un numéro de version si tout fonctionne correctement).

Avertissement⏱ Avant de commencer

Si vous rencontrez des erreurs d’installation, recherchez le message d’erreur sur le web : le dĂ©bogage est une compĂ©tence fondamentale en data science ! La plupart des erreurs trouve une solution sur Stack Overflow dĂšs le premier rĂ©sultat par exemple
 Les chatbots d’IA gĂ©nĂ©rative, comme LeChat de Mistral AI par exemple, peuvent Ă©galement ĂȘtre trĂšs utiles.


1 ReproductibilitĂ© : qu’est-ce que c’est et pourquoi est-ce important ?

⏱ ~45 minutes

1.1 📖 Lectures : la crise de la reproductibilitĂ©

Note📖 Lecture ciblĂ©e (~10 min)

Avant de lire, rĂ©flĂ©chissez : Avez-vous dĂ©jĂ  essayĂ© de rĂ©-exĂ©cuter une analyse et obtenu des chiffres diffĂ©rents ? Avez-vous lu une section Material and Methods d’un article en vous disant « Je n’ai finalement aucune idĂ©e de comment ils ont rĂ©ellement fait telle ou telle Ă©tape » ?

  1. Lisez l’arcile de Nature News « 1 500 scientifiques lĂšvent le voile sur la reproductibilitĂ© » (Baker, 2016).
    Concentrez-vous sur le graphique en barres de l’enquĂȘte et la section « Obstacles Ă  la reproductibilitĂ© » :
    👉 https://www.nature.com/news/1-500-scientists-lift-the-lid-on-reproducibility-1.19970
    (~5 min)

  2. Parcourez la page de présentation de The Turing Way. Lisez « Why this is important » et la liste des obstacles :
    👉 https://book.the-turing-way.org/reproducible-research/overview
    (~5 min)

RĂ©flexion : En santĂ© publique, les enjeux sont particuliĂšrement Ă©levĂ©s. Des rĂ©sultats non reproductibles peuvent influencer des recommandations cliniques ou des dĂ©cisions politiques. Pouvez-vous vous rappeler d’une Ă©tude publiĂ©e sur la COVID-19 en 2020 qui a dĂ» ĂȘtre rĂ©tractĂ©e ou substantiellement corrigĂ©e ? (Indice : cherchez « Surgisphere hydroxychloroquine Lancet » ou « Hydroxychloroquine and azithromycin Gautret Raoult International Journal of Antimicrobial Agents »)


1.2 💡 L’ensemble du spectre de la reproductibilitĂ©

Le terme « reproductible » est parfois utilisé de maniÚre vague, et plusieurs définitions coexistent dans différents domaines scientifiques. Dans ce cours, nous utiliserons la définition ci-dessous, centrée sur la reproductibilité computationnelle :

MĂȘmes donnĂ©es ? MĂȘme code/mĂ©thode ? Ce qui est Ă©valuer
Reproductible ✅ ✅ Peut-on rĂ©-exĂ©cuter l’analyse et obtenir exactement les mĂȘmes chiffres ?
RĂ©plicable ❌ ✅ La mĂȘme mĂ©thode se gĂ©nĂ©ralise-t-elle Ă  de nouvelles donnĂ©es ?
Robuste ✅ ❌ Des choix analytiques diffĂ©rents aboutissent-ils Ă  la mĂȘme conclusion ?
GĂ©nĂ©ralisable ❌ ❌ Le rĂ©sultat tient-il au-delĂ  du contexte original ?

Le diagramme ci-dessous (extrait de The Turing Way) illustre ces 4 niveaux de définition :

Une matrice 2x2 montrant la recherche reproductible, rĂ©plicable, robuste et gĂ©nĂ©ralisable selon les axes mĂȘmes/diffĂ©rentes donnĂ©es et mĂȘme/diffĂ©rent code

Matrice de reproductibilitĂ©. The Turing Way / Scriberia — CC-BY 4.0. Source : https://book.the-turing-way.org

1.3 💡 Pourquoi la reproductibilitĂ© est-elle importante ?

Quelle est la valeur d’un article non reproductible ?
Si ce n’est pas reproductible, est-ce de la science ?
Devrait-on simplement se faire confiance mutuellement ?

Les acteurs de la recherche scientifique doivent ĂȘtre comptable de leurs propres rĂ©sultats. La crĂ©dibilitĂ© scientifique et le professionalisme de chacun repose sur cette capacitĂ© Ă  rendre des comptes. Travailler de maniĂšre reproductible contribue Ă  rĂ©pondre Ă  ces enjeux.

  • 📙 Les revues scientifiques exigent un certain niveau de reproductibilitĂ© : les pairs relecteurs vĂ©rifient dĂ©sormais le code, les donnĂ©es et les workflows/pipelines computationelles avant l’acceptation finale
  • ⚔ La reproductibilitĂ© constitue un bouclier mĂ©thodologique : elle rĂ©duit la probabilitĂ© d’erreurs non dĂ©tectĂ©es et de rĂ©sultats fallacieux
  • đŸ‡ȘđŸ‡șđŸ‡«đŸ‡· Droit institutionnel : l’UE, l’ANR et l’HCERES imposent tous un certain niveau de reproductibilitĂ© pour les recherches qu’elles financent
  • đŸ§± Impact accru : les articles reproductibles sont davantage citĂ©s et repris (fondation plus fiable pour les travaux futurs).

En santĂ© publique, la reproductibilitĂ© revĂȘt une importance particuliĂšre : - Des dĂ©cisions politiques sont prises Ă  partir de rĂ©sultats publiĂ©s. Un rĂ©sultat erronĂ© ou non-reproductible peut ainsi nuire Ă  un grand nombre de patients ou de populations. - La recherche financĂ©e par des fonds publics doit rendre des comptes: si le public a financĂ© l’étude, le code et les donnĂ©es devraient (dans la mesure du possible) ĂȘtre accessibles au public. Cette idĂ©e est Ă©troitement liĂ©e Ă  la science ouverte, un concept connexe Ă  celui de la reproductibilitĂ©, mais distinct (âžĄïžđŸŒ plus de dĂ©tails ici)

Obstacles, motivations et solutions

Obstacle Exemple concret Solution pratique
Culturel « Mon directeur de thÚse ne fait jamais ça » Le présenter comme un investissement de carriÚre, non comme une contrainte supplémentaire
Technique La simulation mets plus de 3 jours Ă  tourner Stocker des rĂ©sultats intermĂ©diaires prĂ©-calculĂ©s ; prĂ©voir un mode d’exĂ©cution rapide rĂ©duit
LĂ©gal DonnĂ©es patients sous RGPD GĂ©nĂ©rer des donnĂ©es synthĂ©tiques de mĂȘme structure ; accorder un accĂšs temporaire restreint Ă  un auditeur
Temps « Je nettoierai le code plus tard » Commencer tÎt : cela représente plus de travail au départ, mais en économise énormément lors des révisions suivantes

La reproductibilité est un atout protecteur, pas un inconvénient

La reproductibilitĂ© (et ses tĂ©moignages) donne de la confiance. En effet, les scientifiques qui font attention Ă  la reproductibilitĂ© de leurs travaux sont plus efficaces sur le long terme : ils peuvent plus facilement s’appuyer sur leurs propres travaux passĂ©s.

La reproductibilité apporte des bénéfices à différentes échelles pour la science :

Bénéfices de la reproductibilité à 3 niveaux différents
🌍 Domaine scientifique đŸ„ Groupe de recherche 🧑‍🔬 Vous-mĂȘme
CrĂ©dibilitĂ© mĂ©thodologique renforcĂ©e Transmission plus rapide aux collaborateurs Finalisation & rĂ©visions d’articles plus rapides
Connaissances cumulatives et extensibles RĂ©duction de la dette technique Transparent & fiable pour l’audience
Risque rĂ©duit d’erreurs publiĂ©es Archivage clair et opposable CompĂ©tences techniques & workflow efficace
Plus de citations
Important🔑 Points clĂ©s Ă  retenir
  • La reproductibilitĂ© est une exigence scientifique : un rĂ©sultat scientifique qui ne peut ĂȘtre reproduit n’a que trĂšs peu (voire aucune) valeur ajoutĂ©e. Dans ce cours, nous nous concentrons sur la reproductibilitĂ© computationnelle, qui n’est qu’une des couches nĂ©cessaires pour reproduire la science (il y a aussi la gĂ©nĂ©ration des donnĂ©es par exemple).
  • La reproductibilitĂ© est un continuum : la reproductibilitĂ© universelle, absolue et permanente est un idĂ©al hors d’atteinte. NĂ©anmoins, nous devons nous efforcer d’amĂ©liorer la reproductibilitĂ© pratique en pensant Ă  la rĂ©utilisation future de nos travaux et Ă  la façon dont nous Ă©tablissons la confiance dans nos rĂ©sultats scientifiques.

1.4 đŸ§‘â€đŸ’» Exercice 1 : CrĂ©er le squelette de votre projet reproductible

AstuceđŸ§‘â€đŸ’» Exercice 1 : Configuration du projet (25 min)

Objectif : Créer un projet bien organisé et portable, sur lequel vous vous appuierez ensuite tout au long de ce cours.


Étape 1 : CrĂ©er un projet

  1. Ouvrez RStudio → Fichier → Nouveau projet → Nouveau rĂ©pertoire → Nouveau projet
  2. Nommez-le repro-phds, choisissez un dossier dont vous vous souviendrez
  3. ✅ Cochez « Utiliser renv avec ce projet » — cela configure automatiquement le suivi des dĂ©pendances
  4. Cliquez sur Créer le projet

Notez le fichier .Rproj dans l’onglet Fichiers: chaque fois que vous ouvrez ce fichier, RStudio dĂ©finit automatiquement le rĂ©pertoire de travail Ă  la racine du projet. Rien que cela permet d’éliminer la grande majoritĂ© des problĂšmes liĂ©s aux chemins.

# Si vous ne l'avez pas encore fait, créez le répertoire et l'environnement ci-dessous
mkdir repro-phds && cd repro-phds

# Créer et activer un environnement virtuel
python -m venv .venv
source .venv/bin/activate          # macOS/Linux
# .venv\Scripts\activate           # Windows – exĂ©cutez la ligne correspondant Ă  votre OS

# Démarrer Python
python

Étape 2 : CrĂ©er une structure de dossiers standard

ExĂ©cutez ceci dans votre console (Ă  l’intĂ©rieur du projet) :

dirs <- c(
  "data/raw",           # DonnĂ©es originales — NE JAMAIS Ă©craser
  "data/processed",     # Données nettoyées / transformées
  "R",                  # Fonctions R réutilisables
  "analysis",           # Les scripts .qmd vont ici
  "output/figures",     # Figures sauvegardĂ©es → fig01_..., fig02_...
  "output/tables"       # Tableaux exportĂ©s → tab01_..., tab02_...
)

invisible(lapply(dirs, dir.create, recursive = TRUE, showWarnings = FALSE))
cat("✅ Dossiers créés !\n")

Exécutez le code python suivant (avec .venv actif, dans repro-phds/) :

import os

dirs = [
    "data/raw",
    "data/processed",
    "src",               # Fichiers source Python / modules
    "analysis",          # Notebooks ou scripts
    "output/figures",
    "output/tables"
]

for d in dirs:
    os.makedirs(d, exist_ok=True)

print("✅ Dossiers créés !")

Votre projet devrait maintenant ressembler Ă  ceci :

repro-phds/
├── data/
│   ├── raw/          ← donnĂ©es originales  (Ă  traiter comme en lecture seule)
│   └── processed/    ← donnĂ©es nettoyĂ©es
├── R/  (ou src/)     ← fonctions / modules rĂ©utilisables
├── analysis/         ← vos scripts et notebooks
├── output/
│   ├── figures/      ← fig01_nom.pdf, fig01_nom.png, ...
│   └── tables/       ← tab01_nom.csv, ...
└── README.md         ← vous l'Ă©crirez Ă  l'Ă©tape suivante

Étape 3 : RĂ©diger un README.md

CrĂ©ez README.md Ă  la racine du projet. Un README est la premiĂšre chose que lit n’importe qui s’intĂ©ressant au projet — y compris votre futur vous. Il doit rĂ©pondre Ă  : À quoi sert ce code ? Comment le lancer ?

Copiez le modĂšle ci-dessous dans votre README.md et remplissez les espaces vides :

# repro-phds — Pratique de la reproductibilitĂ© (SantĂ© Publique)

## Description
Un projet d'analyse de données autonome produit lors du cours
« Outils pour la Science Reproductible » (Licence Santé Publique, [Année]).

## Comment reproduire tous les résultats

1. Ouvrez `repro-phds.Rproj` dans RStudio
   (ou activez `.venv` en Python : `source .venv/bin/activate`).
2. Restaurez les dépendances :
   - `<svg aria-hidden="true" role="img" viewBox="0 0 581 512" style="height:1em;width:1.13em;vertical-align:-0.125em;margin-left:auto;margin-right:auto;font-size:inherit;fill:currentColor;overflow:visible;position:relative;"><path d="M581 226.6C581 119.1 450.9 32 290.5 32S0 119.1 0 226.6C0 322.4 103.3 402 239.4 418.1V480h99.1v-61.5c24.3-2.7 47.6-7.4 69.4-13.9L448 480h112l-67.4-113.7c54.5-35.4 88.4-84.9 88.4-139.7zm-466.8 14.5c0-73.5 98.9-133 220.8-133s211.9 40.7 211.9 133c0 50.1-26.5 85-70.3 106.4-2.4-1.6-4.7-2.9-6.4-3.7-10.2-5.2-27.8-10.5-27.8-10.5s86.6-6.4 86.6-92.7-90.6-87.9-90.6-87.9h-199V361c-74.1-21.5-125.2-67.1-125.2-119.9zm225.1 38.3v-55.6c57.8 0 87.8-6.8 87.8 27.3 0 36.5-38.2 28.3-87.8 28.3zm-.9 72.5H365c10.8 0 18.9 11.7 24 19.2-16.1 1.9-33 2.8-50.6 2.9v-22.1z"/></svg>`{=html} : exécutez `renv::restore()` dans la console
   - Python : `pip install -r requirements.txt`
3. Rendez le rapport principal :
   ouvrez `analysis/report.qmd` et cliquez sur **Render**,
   ou exécutez `quarto render analysis/report.qmd`.

## Durée d'exécution estimée
< 1 minute sur un ordinateur portable standard.

## Informations de session
(Collez ici la sortie de `sessioninfo::session_info()`
aprÚs avoir terminé l'Exercice 4.)

Étape 4 : Verrouiller les dĂ©pendances

renv a déjà été initialisé lors de la création du projet.
AprÚs avoir installé des package, enregistrez leurs versions exactes :

renv::snapshot()
# → "renv.lock has been updated."

Ce fichier est votre assurance contre les bugs du type « ça marchait l’annĂ©e derniĂšre ».
Un collaborateur qui exĂ©cute renv::restore() obtiendra exactement les mĂȘmes version de package.

Dans le terminal, exécutez le code bash suivant :

pip freeze > requirements.txt

# Vérifier qu'il a bien été créé
cat requirements.txt

Un collaborateur peut restaurer cet environnement exact avec :

pip install -r requirements.txt

✅ Auto-Ă©valuation

Valider attentivement les quatre items suivants avant de continuer :

  • getwd() () ou os.getcwd() () renvoie le chemin vers repro-phds/
  • Les six sous-dossiers existent dans l’explorateur de fichiers
  • README.md est Ă  la racine du projet et comporte les trois sections
  • renv.lock () ou requirements.txt () a Ă©tĂ© créé
  • Fermer et rouvrir le projet fonctionne correctement

Reflexions supplĂ©mentaires : Pourquoi data/raw/ devrait-il ĂȘtre traitĂ© comme strictement en lecture seule ? Que se passerait-il si vous sauvegardiez accidentellement une version modifiĂ©e par-dessus votre fichier de donnĂ©es original ?



2 Programmation lettrée avec Quarto

⏱ ~45 minutes

2.1 📖 Lecture : Un document pour les gouverner tous

Note📖 Lecture ciblĂ©e (5 min)

Donald Knuth a introduit la programmation lettrĂ©e dans les annĂ©es 1980 : au lieu d’un code avec des commentaires destinĂ©s principalement aux ordinateurs, on rĂ©dige un document narratif qui contient le code, destinĂ© aux humains. Le rĂ©sultat est un document qui est l’analyse.

  1. Lisez le guide « Hello, Quarto » — essayez de rendre l’exemple de document si vous le pouvez :
    👉 https://quarto.org/docs/get-started/hello/rstudio.html

  2. Gardez la feuille de référence Quarto ouverte tout au long de cette partie :
    👉 https://rstudio.github.io/cheatsheets/quarto.pdf

L’idĂ©e centrale : Quand les figures et les chiffres sont calculĂ©s Ă  l’intĂ©rieur de votre fichier .qmd, il n’y a aucune Ă©tape de copier-coller oĂč un chiffre obsolĂšte pourrait se glisser. RĂ©-exĂ©cutez le document et chaque valeur se met Ă  jour automatiquement.


2.2 💡 Anatomie d’un fichier .qmd

Un fichier Quarto possĂšde trois blocs constitutifs :

┌─────────────────────────────────────────────────────────┐
│  1. En-tĂȘte YAML    -> titre, auteur, type de sortie... │
│─────────────────────────────────────────────────────────│
│  2. Texte Markdown  -> prose, titres, listes, liens     │
│─────────────────────────────────────────────────────────│
│  3. Blocs de code   -> code R ou Python + sa sortie     │
└─────────────────────────────────────────────────────────┘

Schéma Quarto

Une illustration colorée montrant des sorciers lançant des sorts pour transformer du code R en beaux documents de sortie

Figure 1: Quarto (comme son prĂ©dĂ©cesseur Rmarkdown) vous permet de mĂȘler code et texte narratif en un seul document dynamique. Illustration par Allison Horst — CC-BY 4.0.

1. L’en-tĂȘte YAML

Ce entĂȘte se place donc au tout dĂ©but de votre document: il se situe entre des dĂ©limiteurs, ---, tout en haut. Il dĂ©finit par dĂ©faut tout ce qui concerne la sortie et son format global, en utilisant le langage YAML. VOici un exemple ci-dessous.
Attention : l’indentation est importante en YAML.

---
title: "Tendances mondiales de santĂ© — DonnĂ©es Gapminder"
author: "Votre Nom"
date: today                   # remplit automatiquement la date du jour
format:
  html:
    toc: true                 # table des matiĂšres
    code-fold: true           # masquer le code par défaut (le lecteur peut le déplier)
    embed-resources: true     # fichier `HTML` autonome (portable)
execute:
  echo: true                  # afficher le code dans la sortie par défaut
  warning: true               # continuer Ă  afficher les avertissements
  message: false              # supprimer les messages (ex. lors du chargement des packages)
---

2. Texte Markdown

Entre les blocs de code, le texte narratif utilise du Markdown (.md) qui est un format d’édition de texte lĂ©ger. Voici un exemple des outils de bases disponibles avec Markdown :

# Titre de niveau 1
## Titre de niveau 2

Un paragraphe. Mettez le texte en **gras**, *italique*, ou `style code`.

- ÉlĂ©ment de liste Ă  puces 1
- ÉlĂ©ment de liste Ă  puces 2

1. ÉlĂ©ment numĂ©rotĂ© 1
2. ÉlĂ©ment numĂ©rotĂ© 2

[Texte descriptif du lien](https://url.com)
![Texte alternatif de l'image](chemin/vers/image.png){width=50%}

3. Blocs de code

Ces blocs sont dĂ©limitĂ©s par des triples apostrophes inversĂ©es \``, suivies de{r}ou{python}(par exemple) pour spĂ©cifier l'interprĂ©teur du langage de programmation Ă  utiliser. Les options spĂ©cifiques au bloc sont indiquĂ©es en attribuant des valeurs Ă  des mots-clĂ©s spĂ©cifiques au dĂ©but du bloc avec la syntaxe suivante :#| mot-clĂ©: valeur` (pouvant changer les valeurs par dĂ©faut dĂ©finies en tĂȘte si besoin). Voici un exemple de bloc, suivi de sa sortie :

```{r}
#| label: summary-table-r
#| echo: true
#| eval: true

library(gapminder)
head(gapminder)
```
# A tibble: 6 × 6
  country     continent  year lifeExp      pop gdpPercap
  <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
1 Afghanistan Asia       1952    28.8  8425333      779.
2 Afghanistan Asia       1957    30.3  9240934      821.
3 Afghanistan Asia       1962    32.0 10267083      853.
4 Afghanistan Asia       1967    34.0 11537966      836.
5 Afghanistan Asia       1972    36.1 13079460      740.
6 Afghanistan Asia       1977    38.4 14880372      786.

Options clĂ©s du bloc (Ă©crites aprĂšs #| Ă  l’intĂ©rieur du bloc) :

Option Défaut Effet
echo true Afficher le code dans la sortie
eval true Exécuter le code
include true Inclure la sortie du bloc
message true Afficher les messages de chargement des packages
warning true Afficher les avertissements
cache false Mettre en cache les résultats (utile pour le code lent)
label — Nom pour le rĂ©fĂ©rencement croisĂ© des figures / tableaux
fig-cap — LĂ©gende de la figure
fig-width / fig-height — Dimensions de la figure (en pouces)

2.2.1 Code inline

Vous pouvez également insérer des valeurs calculées directement au fil du texte en utilisant `r ` ou `{python}` :

Le jeu de données couvre `r length(unique(gapminder$country))` pays de `r min(gapminder$year)` à `r max(gapminder$year)`

Une fois rendu, cela devient :

Le jeu de données couvre 142 pays de 1952 à 2007

✹ Pas de copier-coller, pas de chiffres obsolùtes, pas de mise à jour manuelle !


2.3 đŸ§‘â€đŸ’» Exercice 2 : Votre premier rapport reproductible en santĂ©

AstuceđŸ§‘â€đŸ’» Exercice 2 : Premier rapport Quarto (25 min)

Objectif : Rédiger un rapport .qmd reproductible qui charge des données, calcule des résumés avec des valeurs inline, et produit un fichier de sortie HTML.

Nous utilisons le jeu de donnĂ©es Gapminder : espĂ©rance de vie, population et PIB par habitant pour 142 pays de 1952 Ă  2007. L’espĂ©rance de vie est une mĂ©trique centrale en santĂ© publique — elle intĂšgre la mortalitĂ© Ă  tous les Ăąges et reflĂšte la performance globale du systĂšme de santĂ©.


Étape 1 : CrĂ©er le fichier

Dans RStudio : Fichier → Nouveau fichier → Document Quarto.
Supprimez tout le contenu du modĂšle. Sauvegardez sous analysis/report.qmd.

Collez l’en-tĂȘte YAML ci-dessous correspondant Ă  votre langage :

---
title: "Tendances mondiales de santĂ© — Analyse Gapminder"
author: "Votre Nom"
date: today
format:
  html:
    toc: true
    code-fold: true
    theme: flatly
    embed-resources: true
execute:
  echo: true
  warning: false
  message: false
---
---
title: "Tendances mondiales de santĂ© — Analyse Gapminder"
author: "Votre Nom"
date: today
format:
  html:
    toc: true
    code-fold: true
    theme: flatly
    embed-resources: true
execute:
  echo: true
  warning: false
  message: false
jupyter: python3
---

Étape 2 : Bloc de configuration (toujours le tout premier bloc !)

Un bloc de configuration s’exĂ©cute silencieusement avant tout le reste. C’est un bon endroit pour dĂ©finir votre graine alĂ©atoire par exemple.

```{r}
#| label: setup-r
#| include: false

set.seed(20260401)      # ← assure la reproductibilitĂ© de tout code reposant sur la gĂ©nĂ©ration de nombre pseudo-alĂ©atoires

library(ggplot2)
library(dplyr)
library(gapminder)
library(here)
library(knitr)
```
```{python}
#| label: setup-py
#| include: false

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

np.random.seed(20260401)

# Charger Gapminder depuis GitHub
url = "https://raw.githubusercontent.com/jennybc/gapminder/main/inst/extdata/gapminder.tsv"
gapminder = pd.read_csv(url, sep="\t")

sns.set_theme(style="whitegrid", palette="colorblind")
```

Étape 3 : Section “DonnĂ©es”, avec calcul de valeurs inline

## Les données

Le jeu de données **Gapminder** est une base de données mondiale sur le développement compilée 
par la Fondation Gapminder. Il couvre des indicateurs de santé, de population et de richesse 
pour **`r length(unique(gapminder$country))` pays** 
sur **`r length(unique(gapminder$year))` points temporels**
(de `r min(gapminder$year)` Ă  `r max(gapminder$year)`).

```{r}
#| label: tbl-preview-r
#| tbl-cap: "Les 6 premiÚres lignes du jeu de données Gapminder."

head(gapminder) |> knitr::kable()
```
## Les données

Le jeu de données **Gapminder** est une base de données mondiale sur le développement compilée 
par la Fondation Gapminder. Il couvre des indicateurs de santé, de population et de richesse 
pour **`{python} gapminder["country"].nunique()` pays** 
sur **`{python} len(sorted(gapminder["year"].unique()))` points temporels**
(de `{python} sorted(gapminder["year"].unique())[0]` Ă  `{python} sorted(gapminder["year"].unique())[-1]`).

```{python}
#| label: tbl-preview-py

gapminder.head(6)
```

Étape 4 : Section “Statistiques descriptives”

## Statistiques descriptives

```{r}
#| label: tbl-continent-2007-r
#| tbl-cap: "Espérance de vie et PIB par habitant par continent en 2007."

gapminder |>
  filter(year == 2007) |>
  group_by(continent) |>
  summarise(
    `N pays`                  = n(),
    `Esp. vie moy.`           = round(mean(lifeExp), 1),
    `Esp. vie méd.`           = round(median(lifeExp), 1),
    `PIB/hab. moyen`          = round(mean(gdpPercap), 0)
  ) |>
  knitr::kable(format.args = list(big.mark = ","))
```

En 2007, l'espérance de vie mondiale moyenne était de
**`r round(mean(dplyr::filter(gapminder, year == 2007)$lifeExp), 1)` ans**,
avec des valeurs allant de
`r round(min(dplyr::filter(gapminder, year == 2007)$lifeExp), 1)` Ă 
`r round(max(dplyr::filter(gapminder, year == 2007)$lifeExp), 1)` ans.
## Statistiques descriptives

```{python}
#| label: tbl-continent-2007-py

    gapminder.query("year == 2007") \
    .groupby("continent") \
    .agg(
        n_countries=("country", "nunique"),
        mean_lifeExp=("lifeExp", "mean"),
        median_lifeExp=("lifeExp", "median"),
        mean_gdpPercap=("gdpPercap", "mean")
    ) \
    .round(1) \
    .reset_index() \
    .rename(columns={
        "continent": "Continent",
        "n_countries": "N Pays",
        "mean_lifeExp": "Esp. vie moy.",
        "median_lifeExp": "Esp. vie méd.",
        "mean_gdpPercap": "PIB/hab. moyen"
    })
```

Étape 5 : Rendu !

Cliquez sur le bouton bleu Render (en haut du volet éditeur), ou appuyez sur Ctrl+Shift+K / Cmd+Shift+K.

Ou encore depuis la console :

quarto::quarto_render("analysis/report.qmd")

Dans le terminal

quarto render analysis/report.qmd

Ouvrez le fichier report.html ainsi obtenu dans votre navigateur. Vérifiez que :

  • Les valeurs inline (nombre de pays, plage d’annĂ©es) apparaissent correctement dans le texte
  • Le tableau de rĂ©sumĂ© a bien une lĂ©gende
  • La bascule « Code » (issue de code-fold: true) fonctionne correctement pour chaque bloc

✅ Auto-Ă©valuation

  • Le fichier HTML se gĂ©nĂšre sans erreurs
  • Les valeurs inline dans le texte correspondent aux valeurs du tableau
  • Changer year == 2007 en year == 1997 et re-gĂ©nĂ©rer met bien Ă  jour toutes les valeurs automatiquement
  • Vous pouvez ouvrir report.html sans RStudio ni aucun logiciel (il est auto-suffisant)

Bonus : Ajoutez une section ## Introduction au-dessus de ## Les donnĂ©es avec deux ou trois phrases sur les raisons pour lesquelles l’espĂ©rance de vie est un indicateur pertinent en santĂ© publique. Essayez d’ajouter une note de bas de page avec la syntaxe [^1] et une citation simple en utilisant un fichier .bib associĂ© Ă  un fichier de srtyle bibliographique .csl.



3 Visualisation des données

⏱ ~40 minutes

3.1 📖 Lecture — La grammaire des graphiques

Note📖 Lecture ciblĂ©e (5 min)

PlutĂŽt que de mĂ©moriser des dizaines de types de graphiques, vous apprenez une grammaire — un ensemble de rĂšgles composables. Tout graphique statistique peut ĂȘtre dĂ©crit comme des donnĂ©es mappĂ©es Ă  des propriĂ©tĂ©s visuelles (position, couleur, taille, forme), rendues par des objets gĂ©omĂ©triques, sur un systĂšme de coordonnĂ©es.

  1. Parcourez la page d’accueil ggplot2 et le premier exemple « Quick start » :
    👉 https://ggplot2.tidyverse.org/
    (Pour les utilisateurs de , lisez plutît l’aperçu du tutoriel seaborn :
    👉 https://seaborn.pydata.org/tutorial/introduction.html)

  2. Lisez le résumé et la premiÚre page de The Grammar of Graphics de Wilkinson, tels que résumés ici :
    👉 https://vita.had.co.nz/papers/layered-grammar.html — uniquement les paragraphes « Abstract » et « Introduction »

IdĂ©e clĂ© : Une fois que vous comprenez cette grammaire, vous pouvez construire presque n’importe quel graphique en composant des couches (rapidement modulables). Vous n’avez plus besoin de chercher « comment faire un graphique en violon en ? » Ă  chaque modification.


3.2 💡 Construire des graphiques couche par couche

Les sept couches

Composant Dans ggplot2 Exemple
Données ggplot(data = ...) gapminder |> filter(year == 2007)
Esthétiques aes(x, y, colour, size, shape) aes(x = gdpPercap, y = lifeExp, colour = continent)
Géométrie geom_*() geom_point(), geom_line(), geom_boxplot()
Échelles scale_*() scale_x_log10(), scale_colour_viridis_d()
Facettes facet_wrap() / facet_grid() facet_wrap(~ continent)
ThĂšme theme_*() theme_minimal()
Étiquettes labs() labs(title = "...", x = "...", caption = "...")

Une illustration artistique d'une personne construisant un graphique ggplot2 en couches

Chaque graphique ggplot2 est construit en superposant ces composants. Illustration par Allison Horst — CC-BY 4.0.

Exemple complet

library(ggplot2)
library(gapminder)
library(dplyr)

gap_2007 <- gapminder |> filter(year == 2007)

ggplot(
  data = gap_2007,
  aes(x = gdpPercap, y = lifeExp,
      colour = continent,
      size   = pop)          # taille des bulles = population
) +
  geom_point(alpha = 0.7) +
  scale_x_log10(labels = scales::dollar_format()) +   # axe PIB en log
  scale_colour_viridis_d(option = "plasma") +         # palette accessible aux daltoniens
  scale_size(range = c(2, 14), guide = "none") +
  labs(
    title    = "Richesse et santé en 2007",
    subtitle = "Chaque bulle est un pays ; taille ∝ population",
    x        = "PIB par habitant (échelle log, USD)",
    y        = "Espérance de vie (années)",
    colour   = "Continent",
    caption  = "Source : Fondation Gapminder"
  ) +
  theme_minimal(base_size = 13)
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

gap_2007 = gapminder[gapminder["year"] == 2007].copy()

# Tailles des bulles proportionnelles Ă  la population
max_pop = gap_2007["pop"].max()
gap_2007["bubble_size"] = (gap_2007["pop"] / max_pop) * 1800 + 30

fig, ax = plt.subplots(figsize=(10, 6))

continents = gap_2007["continent"].unique()
palette = sns.color_palette("plasma", len(continents))

for i, cont in enumerate(sorted(continents)):
    subset = gap_2007[gap_2007["continent"] == cont]
    ax.scatter(
        np.log10(subset["gdpPercap"]),
        subset["lifeExp"],
        s=subset["bubble_size"],
        color=palette[i],
        alpha=0.75,
        label=cont
    )

ax.set_xlabel("PIB par habitant (échelle log, USD)", fontsize=12)
ax.set_ylabel("Espérance de vie (années)", fontsize=12)
ax.set_title("Richesse et santé en 2007", fontsize=14, fontweight="bold")
ax.set_xticks([3, 4, 5])
ax.set_xticklabels(["1 000 $", "10 000 $", "100 000 $"])
ax.legend(title="Continent", loc="lower right")
plt.tight_layout()
plt.show()

Sauvegarder les figures de maniĂšre programmatique

Avertissement⚠ N’utilisez jamais le bouton « Export »

Sauvegarder une figure manuellement (par clic droit ou en cliquant sur « Export » dans le volet Plots) n’est pas reproductible. La taille, la rĂ©solution et le format varient Ă  chaque fois, et c’est une Ă©tape est invisible dans votre code.

Sauvegardez toujours les figures Ă  l’intĂ©rieur de votre script, avec des dimensions et une rĂ©solution fixes.

# 1. Assigner votre graphique à une variable nommée
p <- ggplot(gap_2007, aes(...)) + ...

# 2. Sauvegarder — fournir un vecteur (par exemple `.PDF`) ou un raster (par exempke `.PNG`) selon la nature de votre graphique
ggsave(
  filename = here::here("output", "figures", "fig01_richesse_sante_2007.pdf"),
  plot     = p,
  width    = 10, height = 6, units = "in"
)
ggsave(
  filename = here::here("output", "figures", "fig01_richesse_sante_2007.png"),
  plot     = p,
  width    = 10, height = 6, units = "in",
  dpi      = 300          # 300 dpi = qualité publication
)
fig, ax = plt.subplots(figsize=(10, 6))
# ... votre code de graphique ...

fig.savefig("output/figures/fig01_richesse_sante_2007.pdf", bbox_inches="tight")
fig.savefig("output/figures/fig01_richesse_sante_2007.png", dpi=300, bbox_inches="tight")
plt.close()   # libérer la mémoire

Convention de nommage des fichiers : utilisez un prĂ©fixe numĂ©rique correspondant Ă  votre manuscrit — fig01_, fig02_, 
, tab01_, tab02_, 
 C’est souvent l’un des premiers points que vĂ©rifient les auditeurs.

Choisir des palettes de couleurs accessibles

Environ 8 % des hommes prĂ©sentent une forme de dĂ©ficience de la vision des couleurs. Voici quelques palettes conçues pour ĂȘtre perceptuellement uniformes et accessibles aux daltoniens :

Palette Package /library Cas d’usage
viridis, plasma, magma viridis (intégré dans ggplot2) Séquentiel / continu
scale_colour_viridis_d() ggplot2 Catégoriel discret
scale_colour_brewer(palette = "Set2") ggplot2 CatĂ©goriel (jusqu’à 8 groupes)
sns.set_palette("colorblind") seaborn Tout graphique seaborn
palette="viridis" seaborn Mapping de couleur continu

3.3 đŸ§‘â€đŸ’» Exercice 3 : Figures

AstuceđŸ§‘â€đŸ’» Exercice 3 : Votre premiĂšre figure (20 min)

Objectif : Ajouter deux figures en qualitĂ© “publication” Ă  analysis/report.qmd, et les sauvegarder de maniĂšre programmatique dans output/figures/.


Figure 1 : Évolution de l’espĂ©rance de vie au fil du temps

Ajoutez une nouvelle section ## Tendances au fil du temps Ă  votre rapport :

## Tendances au fil du temps

L'espérance de vie s'est améliorée dans tous les continents depuis 1952 (voir @fig-trends),
mais de grandes disparités persistent.

```{r}
#| label: fig-trends-r
#| fig-cap: "EspĂ©rance de vie mĂ©diane par continent, 1952–2007. Les rubans indiquent l'intervalle interquartile."
#| fig-width: 10
#| fig-height: 5

p_trends <- gapminder |>
  group_by(continent, year) |>
  summarise(
    med  = median(lifeExp),
    q25  = quantile(lifeExp, 0.25),
    q75  = quantile(lifeExp, 0.75),
    .groups = "drop"
  ) |>
  ggplot(aes(x = year, y = med,
             colour = continent, fill = continent)) +
  geom_ribbon(aes(ymin = q25, ymax = q75), alpha = 0.2, colour = NA) +
  geom_line(linewidth = 1.1) +
  geom_point(size = 2.2) +
  scale_colour_viridis_d(option = "plasma") +
  scale_fill_viridis_d(option = "plasma") +
  labs(
    title   = "Tendances de l'espĂ©rance de vie par continent (1952–2007)",
    x       = "Année",
    y       = "Espérance de vie (années)",
    colour  = "Continent", fill = "Continent",
    caption = "Source : Gapminder. Les rubans indiquent l'IQR."
  ) +
  theme_minimal(base_size = 13) +
  theme(legend.position = "bottom")

p_trends

ggsave(
  here::here("output", "figures", "fig02_tendances_par_continent.pdf"),
  plot = p_trends, width = 10, height = 5
)
```
## Tendances au fil du temps

```{python}
#| label: fig-trends-py
#| fig-cap: "EspĂ©rance de vie mĂ©diane par continent, 1952–2007."

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

trend = (
    gapminder
    .groupby(["continent", "year"])["lifeExp"]
    .agg(med="median",
         q25=lambda x: x.quantile(0.25),
         q75=lambda x: x.quantile(0.75))
    .reset_index()
)

palette = sns.color_palette("plasma", n_colors=trend["continent"].nunique())

fig, ax = plt.subplots(figsize=(10, 5))
for i, (cont, grp) in enumerate(trend.groupby("continent")):
    ax.fill_between(grp["year"], grp["q25"], grp["q75"],
                    color=palette[i], alpha=0.2)
    ax.plot(grp["year"], grp["med"], marker="o", markersize=4,
            color=palette[i], label=cont, linewidth=1.5)

ax.set_xlabel("Année", fontsize=12)
ax.set_ylabel("Espérance de vie (années)", fontsize=12)
ax.set_title("Tendances de l'espĂ©rance de vie par continent (1952–2007)", fontsize=14)
ax.legend(loc="lower right", title="Continent")
plt.tight_layout()

fig.savefig("../output/figures/fig02_tendances_par_continent.pdf", bbox_inches="tight")
plt.show()
```

Figure 2 : Distribution de l’espĂ©rance de vie en 2007

Ajoutez une section ## Distribution en 2007 :

## Distribution en 2007

En 2007, la distribution de l'espérance de vie varie largement au sein
de chaque continent (voir @fig-dist-r).

```{r}
#| label: fig-dist-r
#| fig-cap: "Espérance de vie par continent en 2007. Violon = densité ; points = pays individuels ; barre blanche = médiane."
#| fig-width: 9
#| fig-height: 5

p_dist <- gapminder |>
  filter(year == 2007) |>
  ggplot(aes(
    x      = reorder(continent, lifeExp, FUN = median),
    y      = lifeExp,
    fill   = continent,
    colour = continent
  )) +
  geom_violin(alpha = 0.35, linewidth = 0.4) +
  geom_jitter(width = 0.12, alpha = 0.8, size = 2.2) +
  stat_summary(fun = median, geom = "crossbar",
               width = 0.45, colour = "white", linewidth = 0.9) +
  scale_fill_viridis_d(option = "plasma") +
  scale_colour_viridis_d(option = "plasma") +
  labs(
    title   = "Distribution de l'espérance de vie par continent en 2007",
    x       = "Continent (ordonné par espérance de vie médiane)",
    y       = "Espérance de vie (années)",
    caption = "Source : Gapminder. Chaque point = un pays."
  ) +
  theme_minimal(base_size = 13) +
  theme(legend.position = "none")

p_dist

ggsave(
  here::here("output", "figures", "fig03_distribution_2007.pdf"),
  plot = p_dist, width = 9, height = 5
)
```
## Distribution en 2007

En 2007, la distribution de l'espérance de vie varie largement au sein
de chaque continent (voir @fig-dist-py).

```{python}
#| label: fig-dist-py
#| fig-cap: "Espérance de vie par continent en 2007."

gap_2007 = gapminder[gapminder["year"] == 2007].copy()

# Ordonner les continents par espérance de vie médiane
order = (
    gap_2007.groupby("continent")["lifeExp"]
    .median()
    .sort_values()
    .index.tolist()
)

fig, ax = plt.subplots(figsize=(9, 5))
sns.violinplot(data=gap_2007, x="continent", y="lifeExp",
               order=order, palette="plasma", alpha=0.4, ax=ax)
sns.stripplot(data=gap_2007, x="continent", y="lifeExp",
              order=order, palette="plasma", alpha=0.75,
              jitter=True, size=5, ax=ax)

ax.set_xlabel("Continent (ordonné par médiane)", fontsize=12)
ax.set_ylabel("Espérance de vie (années)", fontsize=12)
ax.set_title("Distribution de l'espérance de vie par continent en 2007", fontsize=14)
plt.tight_layout()

fig.savefig("../output/figures/fig03_distribution_2007.pdf", bbox_inches="tight")
plt.show()
```

Références croisées dans le texte narratif

Dans votre rapport, référencez les figures par leur étiquette (remplacez @fig-trends-r par @fig-trends-py si vous utilisez ) :

L'espérance de vie a considérablement progressé depuis 1952 (voir @fig-trends-r),
bien que de larges disparités persistent entre et au sein des continents
(@fig-dist-r).

✅ Auto-Ă©valuation

  • Les deux figures apparaissent dans le HTML gĂ©nĂ©rĂ©
  • Deux fichiers PDF existent dans output/figures/ avec des noms descriptifs
  • Les noms de fichiers suivent la convention de prĂ©fixe fig02_, fig03_
  • Les deux figures utilisent une palette accessible aux daltoniens
  • Chaque figure a une lĂ©gende informative fig-cap

DĂ©fi bonus : Ajoutez une 3e figure : un nuage de points pour l’Afrique uniquement montrant comment le PIB par habitant est liĂ© Ă  l’espĂ©rance de vie Ă  chaque dĂ©cennie. La relation est-elle la mĂȘme qu’à l’échelle mondiale ? Évolue-t-elle dans le temps ?



4 Partage & check-liste de reproductibilité

⏱ ~35 minutes

4.1 📖 Lecture — L’audit de la revue

Note📖 Lecture ciblĂ©e (5 min)

Le Biometrical Journal — une revue de biostatistique — effectue des audits de reproductibilitĂ© sur chaque article acceptĂ©. Les manuscrits reçoivent une check-liste et ne peuvent ĂȘtre publiĂ©s que lorsque tous les points sont validĂ©s. C’est une pratique de plus en plus rĂ©pandue dans les revues scientifiques.

  1. Lisez l’EncadrĂ© 1 et l’Introduction de :
    Hejblum et al. (2020). Realistic and robust reproducible research for biostatistics.
    👉 https://www.biorxiv.org/content/10.1101/2020.01.15.907485v1
    (~5 min — concentrez-vous sur les 10 points de la check-liste)

  2. Parcourez la section Turing Way sur « Making Research Reproducible » :
    👉 https://book.the-turing-way.org/reproducible-research/reproducible-research

Demandez-vous : Si vous soumettez votre projet repro-phds à un audit de revue maintenant, quels point parmis les 10 de la check-liste ne seraient pas cochés ?

4.2 💡 Outils pour partager et archiver

Une chaĂźne d’outils complĂšte pour la reproductibilitĂ©

Passer de « ça fonctionne sur ma machine » Ă  « n’importe qui peut l’exĂ©cuter » nĂ©cessite d’empiler plusieurs couches de solutions :

📁  Organisation du projet      Projets RStudio / structure de dossiers standard
🔒  Gestion des dĂ©pendances     renv  (`<svg aria-hidden="true" role="img" viewBox="0 0 581 512" style="height:1em;width:1.13em;vertical-align:-0.125em;margin-left:auto;margin-right:auto;font-size:inherit;fill:currentColor;overflow:visible;position:relative;"><path d="M581 226.6C581 119.1 450.9 32 290.5 32S0 119.1 0 226.6C0 322.4 103.3 402 239.4 418.1V480h99.1v-61.5c24.3-2.7 47.6-7.4 69.4-13.9L448 480h112l-67.4-113.7c54.5-35.4 88.4-84.9 88.4-139.7zm-466.8 14.5c0-73.5 98.9-133 220.8-133s211.9 40.7 211.9 133c0 50.1-26.5 85-70.3 106.4-2.4-1.6-4.7-2.9-6.4-3.7-10.2-5.2-27.8-10.5-27.8-10.5s86.6-6.4 86.6-92.7-90.6-87.9-90.6-87.9h-199V361c-74.1-21.5-125.2-67.1-125.2-119.9zm225.1 38.3v-55.6c57.8 0 87.8-6.8 87.8 27.3 0 36.5-38.2 28.3-87.8 28.3zm-.9 72.5H365c10.8 0 18.9 11.7 24 19.2-16.1 1.9-33 2.8-50.6 2.9v-22.1z"/></svg>`{=html})  /  venv + requirements.txt  (`<svg aria-hidden="true" role="img" viewBox="0 0 448 512" style="height:1em;width:0.88em;vertical-align:-0.125em;margin-left:auto;margin-right:auto;font-size:inherit;fill:currentColor;overflow:visible;position:relative;"><path d="M439.8 200.5c-7.7-30.9-22.3-54.2-53.4-54.2h-40.1v47.4c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3zM167.8 248.1h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4zm-6.7-142.6c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4 11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3z"/></svg>`{=html})
📝  Document lettrĂ©             Quarto (.qmd)
đŸŽČ  Graines alĂ©atoires          set.seed() / np.random.seed()
đŸ—‚ïž  ContrĂŽle de version         Git
🌐  HĂ©bergement distant         GitHub
📩  Archivage permanent         Zenodo  →  DOI citable dans un article

renv et environnements virtuels

renv crée une bibliothÚque locale au projet et enregistre les versions exactes des packages dans renv.lock.

renv::snapshot()    # mettre Ă  jour le fichier de verrouillage aprĂšs installation/modification de packages
renv::restore()     # commande pour le collaborateur : installer exactement les mĂȘmes versions
renv::status()      # vérifier si le fichier de verrouillage et l'état actuel concordent

À la fin de votre rapport, enregistrez toujours votre environnement de session :

sessioninfo::session_info()

Cela affiche la version de , le systĂšme d’exploitation, et la version exacte de chaque package chargĂ©.

Dans le terminal, comme mentionné dans Section 1

pip freeze > requirements.txt       # sauvegarder les versions exactes

# Configuration pour le collaborateur
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

À la fin de votre notebook :

## Dépendances

```{python}
import sys, importlib.metadata
print(f"Python {sys.version}")
for pkg in ["pandas", "matplotlib", "seaborn", "numpy"]:
    print(f"  {pkg}: {importlib.metadata.version(pkg)}")
```

Git et GitHub : l’essentiel

Pourquoi utiliser git et GitHub ?

🎖 Sauvegarde hors site : si votre ordinateur tombe en panne, rien n’est perdu
🎖 Historique complet : vous pouvez remonter dans le temps, jusqu’à n’importe quelle version prĂ©cĂ©dente, sans craindre d’avoir supprimĂ© par inadvertance du code que vous pourriez rĂ©utiliser plus tard
🎖 Collaboration : les autres peuvent contribuer facilement, sans s’envoyer des fichiers par e-mail
🎖 IntĂ©gration avec Zenodo (pour des DOI citables)

  • git est un systĂšme de contrĂŽle de version qui permet de suivre les modifications de tous les fichiers d’un projet, et de synchroniser ces modifications entre plusieurs ordinateurs et contributeurs.
  • GitHub est une plateforme web de Microsoft fournissant l’intĂ©gration de git avec l’hĂ©bergement cloud.

Vous n’avez pas besoin d’ĂȘtre un expert git : trois commandes couvrent la majeure partie d’’usage quotidien :

git add .                                                 # indexer toutes les modifications
git commit -m "Ajout analyse espérance de vie et figures" # messages décrivant les modifications indexées
git push                                                  # envoyer vers GitHub
Note🐙 Configuration unique de git
git config --global user.name  "Votre nom d'utilisateur"
git config --global user.email "vous@domaine.ext"

Dans RStudio : Outils → Options globales → Git/SVN — pointez vers l’exĂ©cutable git . Pour tout problĂšme de configuration de git dans RStudio, vous pouvez consulter le livre en ligne Happy git with R.

Zenodo : un DOI permanent pour votre code (et optionnellement vos données)

Zenodo est un dĂ©pĂŽt hĂ©bergĂ© par le CERN qui attribue Ă  votre code ou Ă  vos donnĂ©es un DOI (qui signifie Digital Object Identifier), un identifiant permanent et citable. C’est ce qui figure dans la dĂ©claration de DisponibilitĂ© des donnĂ©es de votre article.

Comment ça fonctionne en trois étapes :

  1. Publiez votre projet dans un dépÎt GitHub public
  2. Connectez GitHub sur https://zenodo.org/account/settings/github
  3. CrĂ©ez une release GitHub (ex. v1.0) — Zenodo l’archive automatiquement et Ă©met un DOI

Votre article cite ensuite :
> « L’ensemble du code d’analyse est disponible sur https://doi.org/10.5281/zenodo.XXXXXXX »

Le fait qu’il possĂšde un DOI et soit hĂ©bergĂ© par l’UE le rend beaucoup plus pĂ©renne qu’un simple dĂ©pĂŽt GitHub (d’autant qu’ils ne sont pas exclusifs l’un de l’autre).

4.3 đŸ§‘â€đŸ’» Exercice 4 : Auto-audit et prĂ©paration au partage

AstuceđŸ§‘â€đŸ’» Exercice 4 : VĂ©rifier la check-liste RR (20 min)

Objectif : Auditer systématiquement votre projet repro-phds par rapport à la check-liste standard, corriger les lacunes et le préparer au partage.


Étape 1 : La check-liste

Parcourez chaque point. Pour tout ce qui n’est pas encore en place, ajoutez-le maintenant :

đŸ—‚ïž README & exĂ©cution

  • README.md dĂ©crit le projet en un paragraphe
  • Le README donne des instructions prĂ©cises pour reproduire tous les rĂ©sultats (quel fichier, quelle commande)
  • Une seule commande rĂ©-exĂ©cute tout (quarto render analysis/report.qmd)
  • La durĂ©e d’exĂ©cution est documentĂ©e (ex. « < 1 minute sur un ordinateur portable standard »)

📩 DĂ©pendances

  • renv.lock () ou requirements.txt () est prĂ©sent et Ă  jour
  • sessioninfo::session_info() () ou la sortie Python Ă©quivalente est affichĂ©e dans le rapport

📊 DonnĂ©es & code

  • Tous les scripts nĂ©cessaires pour reproduire les rĂ©sultats sont Ă  l’intĂ©rieur du projet
  • Les donnĂ©es sont soit dans data/raw/, soit tĂ©lĂ©chargĂ©es via une URL stable dans le code
  • Aucun chemin absolu nulle part dans le code (/home/alice/
 ou C:
)

đŸŽČ AlĂ©atoire

  • set.seed() () ou np.random.seed() () est dĂ©fini dans le bloc de configuration

📁 Sortie

  • Toutes les figures sont sauvegardĂ©es de maniĂšre programmatique dans output/figures/
  • Les noms de fichiers de figures utilisent la convention de prĂ©fixe fig01_, fig02_ correspondant au rapport
  • Au moins un tableau est sauvegardĂ© dans output/tables/

Étape 2 : Ajouter les informations de session au README

Ajoutez la sortie de la commande session-info en bas de votre README.md :

# Exécuter dans la console et coller la sortie dans README.md
sessioninfo::session_info()
# Exécuter dans le terminal et coller dans README.md
python -c "import sys; print(sys.version)"
python -m pip list

Étape 3 : InstantanĂ© final des dĂ©pendances et rendu propre

# Mettre Ă  jour le fichier de verrouillage
renv::snapshot()

# Le test ultime — redĂ©marrer R complĂštement, puis rendre de zĂ©ro :
# Session → RedĂ©marrer R  (ou Ctrl+Shift+F10)
renv::restore()
quarto::quarto_render("analysis/report.qmd")
pip freeze > requirements.txt

# Désactiver et réactiver l'environnement, puis rendre
deactivate
source .venv/bin/activate
pip install -r requirements.txt
quarto render analysis/report.qmd

Étape 4 : Exporter un tableau

library(gapminder)
library(dplyr)
library(readr)
library(here)

summary_2007 <- gapminder |>
  filter(year == 2007) |>
  group_by(continent) |>
  summarise(
    n_countries    = n(),
    mean_lifeExp   = round(mean(lifeExp), 2),
    median_lifeExp = round(median(lifeExp), 2),
    mean_gdpPercap = round(mean(gdpPercap), 0)
  )

write_csv(summary_2007,
          here("output", "tables", "tab01_continent_summary_2007.csv"))
import pandas as pd

summary_2007 = (
    gapminder.query("year == 2007") \
    .groupby("continent") \
    .agg(
        n_countries=("country", "nunique"),
        mean_lifeExp=("lifeExp", "mean"),
        median_lifeExp=("lifeExp", "median"),
        mean_gdpPercap=("gdpPercap", "mean")
    ) \
    .round(2) \
    .reset_index()
)

summary_2007.to_csv("output/tables/tab01_continent_summary_2007.csv",
                    index=False)

Étape 5 (Bonus) — Push sur GitHub, et archiver sur Zenodo

# 1. Initialiser Git (à ignorer si c'est déjà fait)
git init
git add .
git commit -m "Analyse reproductible initiale — EspĂ©rance de vie Gapminder"

# 2. Créer un nouveau dépÎt sur https://github.com/new, puis :
git remote add origin https://github.com/VOTRE_NOM/repro-phds.git
git push -u origin main

# 3. CrĂ©er une release sur GitHub (cliquez « Releases » → « Create a new release »)
#    Étiquetez-la : v1.0.0

# 4. Allez sur https://zenodo.org/account/settings/github
#    Activez le dĂ©pĂŽt → la release dĂ©clenche la crĂ©ation automatique d'un DOI

✅ VĂ©rification finale

Le test ultime de reproductibilité :
Demandez Ă  un camarade de cloner ou tĂ©lĂ©charger votre dĂ©pĂŽt, de suivre exactement vos instructions README, et d’essayer de reproduire vos figures sans vous demander quoi que ce soit.

Si c’est possible — vous avez un projet reproductible. 🎉

  • Les 13 points de la check-liste ci-dessus sont cochĂ©s
  • Le projet se rend Ă  partir d’une session /Python propre
  • Un camarade peut reproduire vos figures Ă  partir des seules instructions du README
  • (Bonus) Le projet est sur GitHub avec un DOI Zenodo

Questions de réflexion :

  1. Quel Ă©tait le point de la check-liste le plus difficile Ă  satisfaire — et pourquoi ?
  2. GrossiÚrement, combien de temps supplémentaire la mise en place reproductible vous a-t-elle coûté, comparé à « juste écrire du code » ?
  3. RĂ©flechissez un scĂ©nario rĂ©el en santĂ© publique oĂč ce coĂ»t supplĂ©mentaire vaudrait clairement la peine.


🏆 RĂ©sumĂ© & conclusion

Ce que nous avons appris :

🎖 Adopter une structure propre et portable pour une navigation aisĂ©e dans votre projet
🎖 Tout exĂ©cuter de bout en bout avec une seule commande
🎖 Sauvegarder les figures de maniùre programmatique
🎖 Verrouiller vos dĂ©pendances, pour que l’environnement soit reproductible
🎖 IntĂ©grer des valeurs calculĂ©es inline
🎖 Satisfaire aux exigences d’une liste de contrĂŽle de reproductibilitĂ© de revue

La rùgle d’or

Commencez petit, commencez maintenant. La reproductibilité est un idéal ; chaque petit pas en avant vous en rapproche.

Outils clés

Outil ProblÚme résolu Une commande à retenir
RStudio Project Plus de chemins absolus ; espace de travail autonome Ouvrir .Rproj
Quarto Code + prose en un seul document ; pas de copier-coller de valeurs quarto render
renv / venv Versions exactes des packages — assurance « ça marchait l’annĂ©e derniĂšre » renv::snapshot()
here Chemins de fichiers portables fonctionnant sous tous les OS here::here(“output”,“fig.pdf”)
ggplot2 / seaborn Figures programmatiques, cohérentes et exportables ggsave() / fig.savefig()
Git + GitHub Historique des versions, collaboration, sauvegarde hors site git add . && git commit && git push
Zenodo DOI permanent pour citer le code dans les articles Connecter GitHub dans les paramĂštres Zenodo

Pour aller plus loin

Ressource À quoi ça sert
The Turing Way Guide complet et maintenu par la communauté pour la recherche reproductible
R for Data Science (2e) Tidyverse, ggplot2, Quarto — livre gratuit en ligne
What They Forgot to Teach You About R Organisation des projets, nommage, chemins de fichiers
Documentation Quarto Tout sur Quarto
ggplot2 book (3e) Plongée approfondie dans la grammaire des graphiques
Python Data Science Handbook NumPy, Pandas, Matplotlib, scikit-learn
Hejblum et al. (2020) Recherche reproductible pour la biostatistique
Hornung et al. (2026) Surmonter les obstacles à la reproductibilité computationnelle
Ouvrir la Science Guides et passeports de science ouverte français (MESRI)