# 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.
Outils pour une science reproductible, ouverte et communicable
Diplôme Universitaire Public Health Data Science
Avant-propos et instructions
⚙️ Configuration (avant de commencer 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 la 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", # compilation des .qmd depuis R
"knitr", # moteur de compilation
"sessioninfo" # documenter votre environnement logiciel
))Vérifiez que Quarto est bien installé et accessible depuis le terminal : dans l’onglet Terminal de RStudio, tapez quarto --version.
La commande doit renvoyer 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 à l’aide des commandes suivantes :
# 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 plotnine jupyterlab quarto-cli pyprojrootVérifiez que Quarto est bien installé et accessible en exécutant quarto --version dans le terminal. La commande doit renvoyer un numéro de version si tout fonctionne correctement).
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 ont une solution rapidement identifiable sur Stack Overflow par exemple… Les chatbots d’IA générative, comme Vibe 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 minutes1.1 📖 Lectures : la crise de la reproductibilité
1.2 💡 La reproductibilité sous tous ses angles
Le terme « reproductible » est parfois employé de façon imprécise, 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 évalué | |
|---|---|---|---|
| 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 quatre définitions :
1.3 💡 Pourquoi la reproductibilité est 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 chercheurs et chercheuses sont comptables de leurs résultats scientifiques. La crédibilité scientifique et le professionnalisme de chacun reposent sur cette capacité à rendre des comptes. Travailler de manière reproductible, en rendant ses méthodes et ses résultats vérifiables, contribue à répondre à ces enjeux.
- 📙 Les revues scientifiques exigent un certain niveau de reproductibilité : les pairs ne se contentent plus de relire et d’évaluer les manuscrits, ils vérifient aussi désormais le code, les données et les workflows/pipelines computationnels avant l’acceptation finale pour publication.
- 🛡️ 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’Union Européenne, l’Agence Nationale de la Recherche (ANR), et le Haut Conseil de l’évaluation de la recherche et de l’enseignement supérieur (Hcéres) notamment imposent tous un certain niveau de reproductibilité pour les recherches qu’elles financent.
- 🧱 Impact accru : les articles reproductibles sont davantage cités et réutilisés (ils constituent des bases plus fiables pour les travaux ultérieurs).
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 met 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 structure identique ; accorder un accès temporaire restreint à un auditeur |
| Temps | « Je nettoierai le code plus tard » | Commencer tôt : cela représente plus de travail et de temps au départ, mais en économise énormément lors des révisions suivantes |
La reproductibilité représente un atout, une garantie, et n’est pas un frein
La reproductibilité et ses gages renforcent de la confiance. En effet, les scientifiques qui font attention à la reproductibilité de leurs travaux gagnent en efficacité sur le long terme : ils peuvent plus facilement s’appuyer sur leurs propres travaux passés.
La reproductibilité bénéficie à la science à plusieurs niveaux :
| 🌍 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 d’erreurs publiées réduit | Archivage clair et opposable | Compétences techniques & workflow efficace |
| Plus de citations |
1.4 🧑💻 Exercice 1 : Créer le squelette de votre projet reproductible
2 Programmation lettrée avec Quarto
⏱ ~45 minutes
2.1 📖 Lectures : Un document pour les gouverner tous
2.2 💡 Anatomie d’un fichier .qmd
Un fichier Quarto comporte trois éléments principaux :
┌─────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────┘
Quarto (comme son prédécesseur, Rmarkdown) permet de combiner du code et du texte narratif dans un seul document dynamique. Illustration par Allison Horst — CC-BY 4.0.
1. L’en-tête YAML
Un en-tête YAML se trouve au tout début du document, entre deux lignes contenant uniquement --- qui le délimitent. Il définit notamment les paramètres de sortie et le format général du document. En voici un exemple. 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 chunks de code, le texte narratif est rédigé en Markdown (.md), un langage de balisage léger. Voici quelques éléments de syntaxe courants :
# 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)
{width=50%}3. chunks de code
Ces chunks 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 chunk sont indiquées en attribuant des valeurs à des mots-clés spécifiques au début du chunk 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 chunk, suivi de sa sortie :
```{r}
#| label: summary-table-r
#| echo: true
#| eval: true
library(gapminder)
head(gapminder)
```Principales options des chunks (écrites après #| à l’intérieur du chunk) :
| Option | Défaut | Effet |
|---|---|---|
echo |
true |
Afficher le code dans la sortie |
eval |
true |
Exécuter le code |
include |
true |
Inclure la sortie du chunk |
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) |
Code inline
Vous pouvez également insérer dans le texte des valeurs calculées automatiquement 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)`
Après la compilation, le texte affiché est :
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 Quarto
3 Visualisation des données
⏱ ~40 minutes3.1 📖 Lectures : la grammaire des graphiques
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 = "...") |
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 = expression("Chaque bulle est un pays ; taille" %prop% "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)from plotnine import (ggplot, aes, geom_point, scale_x_log10, scale_size,
scale_colour_cmap_d, labs, theme_minimal)
from mizani.labels import label_dollar
gap_2007 = gapminder[gapminder["year"] == 2007]
(
ggplot(gap_2007,
aes(x="gdpPercap", y="lifeExp",
colour="continent",
size="pop")) # taille des bulles = population
+ geom_point(alpha=0.7)
+ scale_x_log10(labels=label_dollar(precision=0, big_mark=",")) # axe PIB en log
+ scale_colour_cmap_d("plasma") # palette accessible aux daltoniens
+ scale_size(range=(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)
)Sauvegarder les figures de manière programmatique
L’enregistrement manuel d’une figure (par clic droit ou à l’aide du bouton « Export » dans le volet Plots) n’est pas reproductible : la taille, la résolution et le format varient à chaque fois, et cette opération n’est pas consignée dans le code (cette étape reste invisible).
Enregistrez toujours les figures depuis 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 format vectoriel (par exemple `.PDF`) ou un raster (par exemple `.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
)from pyprojroot import here
# 1. Assigner votre graphique à une variable nommée
p = ggplot(gap_2007, aes(...)) + ...
... votre code de graphique ...
# 2. Enregistrer dans un format vectoriel (par exemple `.PDF`) ou un raster (par exemple `.PNG`) selon la nature de votre graphique
p.save(
here("output/figures/fig01_richesse_sante_2007.pdf"),
width=10, height=6, units="in", verbose=False
)
p.save(
here("output/figures/fig01_richesse_sante_2007.png"),
width=10, height=6, units="in",
dpi=300, verbose=False # 300 dpi = qualité publication
)Convention de nommage des fichiers : utilisez un préfixe numérique cohérent avec l’ordre des figures et des tableaux dans votre document — fig01_, fig02_, …, tab01_, tab02_, …
Choisir des palettes de couleurs accessibles
Environ 8 % des hommes ont une forme de déficience de la vision des couleurs en France (d’après la Société Française d’Ophtalmologie). Voici quelques palettes conçues pour être perceptuellement uniformes et plus accessibles aux personnes daltoniennes :
| 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) |
scale_colour_cmap_d("viridis") |
plotnine | Catégoriel discret |
scale_colour_cmap("viridis") |
plotnine | Mapping de couleur continu |
3.3 🧑💻 Exercice 3 : Figures
4 Partage & checklist de reproductibilité
⏱ ~35 minutes4.1 📖 Lectures : audit de reproductibilité par les revues scientifiques
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 de combiner plusieurs outils complémentaires :
📁 Organisation du projet Projets RStudio / structure de dossiers standard
🔒 Gestion des dépendances `renv` (R) / `venv` + requirements.txt (Python)
📝 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 sous et environnements virtuels sous
renv crée une bibliothèque de packages propre au projet et consigne dans le fichier de verrouillage renv.lock les versions exactes des packages telles qu’utilisées.
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 document .qmd, enregistrez toujours votre environnement logiciel :
sessioninfo::session_info()Cette commande affiche la version de , le système d’exploitation, et les versions exactes des packages chargés.
Dans le terminal, comme mentionné dans la 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", "numpy", "plotnine"]:
print(f" {pkg}: {importlib.metadata.version(pkg)}")
```git et GitHub : l’essentiel
Pourquoi utiliser git et GitHub ?
🎖 Sauvegarde distante : 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 (attribution de DOI citables)
gitest un système de contrôle de version qui permet de suivre les modifications de tous les fichiers d’un projet, et de synchroniser les modifications entre plusieurs ordinateurs et faciliter le travail à plusieurs.- GitHub est une plateforme en ligne de Microsoft fournissant l’intégration de
gitavec l’hébergement cloud.
Vous n’avez pas besoin d’être un expert git , trois commandes couvrent la majeure partie des usages quotidiens :
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 GitHubgit
git config --global user.name "Votre nom d'utilisateur"
git config --global user.email "vous@domaine.ext"Dans RStudio : Tools → Global Options… → Git/SVN — pointez vers l’exécutable git . En cas de problème de configuration de git dans RStudio, vous pouvez consulter le livre en ligne Happy git with R.
Zenodo : un DOI pérenne pour votre code (et vos données, le cas échéant)
Zenodo est une archive en ligne hébergée par le CERN (Organisation européenne pour la recherche nucléaire), qui permet d’attribuer un DOI (Digital Object Identifier, un identifiant permanent et citable), à une version de votre code et/ou à vos données . Ce DOI peut par exemple être mentionné dans la section Data availability des manuscrits scientifiques.
Fonctionnement simple en trois étapes :
- Vérifiez que le dépôt GitHub hébergeant votre projet est bien public
- Connectez votre compte GitHub à Zenodo depuis https://zenodo.org/account/settings/github
- Créez une release GitHub (ex.
v1.0) => Zenodo archive cette version automatiquement et lui attribue un DOI
Votre article peut ensuite facilement citer (en remplaçant XXXXXXX par le DOI réel) :
> « 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 qu’il soit hébergé en Europe, 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 de la checklist de la Recherche Reproductible et préparation au partage
🏆 Résumé et conclusion
Ce que nous avons appris :
🎖 Adopter une structure claire et portable pour une navigation aisée dans votre projet
🎖 Tout exécuter de bout en bout à l’aide d’une seule commande
🎖 Enregistrer les figures et les tableaux de résultats de manière programmatique
🎖 Figer les versions des dépendances utilisées, pour que l’environnement logiciel soit également reproductible
🎖 Insérer des valeurs calculées inline directement dans le texte
🎖 Satisfaire aux exigences d’une checklist de reproductibilité telle qu’utilisée par les revues scientifiques
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 / pyprojroot | Chemins de fichiers portables fonctionnant sous tous les OS |
here::here(“output”,“fig.pdf”) / here(“output/fig.pdf”)
|
| ggplot2 / plotnine | Figures programmatiques, cohérentes et exportables |
ggsave() / p.save()
|
| 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) | Ouvrage en ligne gratuit consacré à tidyverse, ggplot2 et Quarto |
| What They Forgot to Teach You About R | Organisation des projets, conventions de nommage, chemins de fichiers |
Documentation Quarto |
Tout sur Quarto |
| ggplot2 book (3e) | Présentation approfondie de la grammaire des graphiques |
| Python Data Science Handbook | NumPy, pandas, Matplotlib, scikit-learn |
| Hejblum et al. (2020) | Recherche reproductible en biostatistique |
| Hornung et al. (2026) | Surmonter les obstacles à la reproductibilité computationnelle dans la publication scientifique |
| Ouvrir la Science | Guides et passeports de science ouverte publiés par le gouvernement français (MESRI) |