Leçon 1 sur 8
Unité · Le projet sur le disque
Trois sortes de fichiers, et une seule est éditable
Les données brutes sont en lecture seule, les données dérivées sont jetables, et le code est la seule chose que quiconque édite. Se tromper sur cette frontière est la façon dont une analyse devient irreproductible sans que personne s'en aperçoive pendant onze mois.
L’organisation
project/
data/
raw/ never edited, never written to, ideally chmod -w
reference/ lookup tables, thresholds, admin boundary codes
R/ or src/ the only files anyone edits
outputs/
derived/ cleaned data, disposable
figures/ charts and the CSV of values behind each
reports/ rendered documents
tests/
README.md
environment lock uv.lock or renv.lock
Trois sortes de fichiers, et la distinction n’est pas une question de rangement.
Les données brutes sont en lecture seule. L’export de CommCare, le CSV de DHIS2,
le tableur envoyé par le ministère. Une fois arrivé dans data/raw/, rien n’y écrit
et personne ne l’ouvre dans Excel pour corriger une faute de frappe — un fichier brut
corrigé est un fichier dont vous avez détruit la provenance.
Les données dérivées sont jetables. Tout ce qui est dans outputs/ peut être
supprimé à tout moment et reproduit en exécutant le code. Si supprimer outputs/ fait
perdre quelque chose, ce quelque chose n’était pas dérivé et a sa place ailleurs.
Le code est la seule chose éditée. Chaque correction, chaque recodage, chaque exclusion est une ligne de code, ce qui la rend visible, relisible et réexécutable.
Le test qui décide si c’est correct
rm -rf outputs/ && make all # or: python run.py, Rscript run.R
git status --short # should be empty
Supprimez chaque sortie, relancez, et le dépôt doit paraître intact. Cette seule commande est toute la reproductibilité en tant que propriété opérationnelle, et elle est inconfortable la première fois.
Trois façons dont cela échoue généralement, et chacune nomme quelque chose de réel :
Un fichier dans outputs/ que rien ne produit. Quelqu’un l’a fait à la main, une
fois, et chaque exécution depuis en dépend. C’est une donnée brute portant le mauvais
nom.
Une étape qui ne s’exécute qu’en interactif. Une cellule dans un carnet, une ligne collée dans une console, un téléchargement manuel. Si ce n’est pas dans un script, cela n’a pas eu lieu.
Quelque chose qui doit être exécuté dans un ordre précis et ne le dit pas. La chaîne fonctionne sur votre machine parce que vous connaissez l’ordre.
Rendez les données brutes non modifiables, littéralement
chmod -R a-w data/raw/
# In R, the equivalent discipline is a function that only ever reads:
read_raw <- function(name) readr::read_csv(file.path("data/raw", name))
Cela coûte une commande et prévient l’échec qu’elle nomme. Un
to_csv("data/raw/survey.csv") accidentel dans un carnet est la chose la plus
destructrice que fasse un analyste, elle ne produit aucune erreur, et rien en aval ne
peut la détecter après coup.
Là où le fichier brut est volumineux ou sensible, commitez plutôt sa somme de contrôle.
import hashlib, pathlib
def fingerprint(path: pathlib.Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()[:16]
print(fingerprint(pathlib.Path("data/raw/survey-2025.csv")))
tools::md5sum("data/raw/survey-2025.csv")
Une somme de contrôle dans le dépôt transforme « est-ce le même export ? » en une question qui a une réponse. Quatre-vingt-dix pour cent des « les nombres ont changé et je ne sais pas pourquoi » sont un fichier source qui a changé sans que personne le remarque.
Le nommage, qui est de la provenance
| Nom | Ce qu’il vous apprend |
|---|---|
survey.csv |
Rien |
final_survey_v2_FINAL.xlsx |
Qu’il y en a plusieurs et que celui-ci a gagné une dispute |
household-survey-2025.v1.csv |
Quoi, quand, et quelle version |
Versionnez par le nom de fichier, jamais par écrasement. Les jeux de données de
cette plateforme font exactement cela : une correction est livrée en .v2.csv et ne
remplace jamais .v1.csv, parce qu’un carnet accroché à la v1 doit continuer de
reproduire.
C’est pourquoi les fichiers de données peuvent être mis en cache de façon immuable, et pourquoi les PDF de cours — qui, eux, sont régénérés sur place — ne le peuvent délibérément pas.
Ce qui va dans le dépôt
| Dedans | Dehors |
|---|---|
| Le code, chaque script | Les données brutes à caractère personnel |
| Le fichier de verrouillage d’environnement | Tout ce qui dépasse une cinquantaine de Mo |
| Les petites tables de référence | Identifiants, jetons, chaînes de connexion |
| Les sorties générées que la compilation ne peut pas reconstruire | .Rhistory, __pycache__, .DS_Store |
| Un README | Les sorties qui se régénèrent en quelques secondes |
La quatrième ligne est un jugement plutôt qu’une règle. Cette plateforme commite ses PDF, diaporamas et figures produits — parce que le déploiement tourne sur Cloudflare sans TeX ni Python, si bien qu’un contributeur sans la chaîne d’outils peut quand même livrer un changement de contenu. Commitez un artefact produit quand le reconstruire n’est pas à la portée de tous ceux qui en ont besoin, et pas autrement.
Le README qui est réellement lu
Quatre sections, et il vieillit moins vite qu’un long.
# Nutrition surveillance analysis, Artibonite
## What this produces
A quarterly GAM estimate by commune, and the figures in the cluster report.
## Run it
uv sync
uv run python run.py
## Where the data comes from
data/raw/muac-screening-*.csv — monthly export from the screening database,
downloaded by the M&E officer on the 5th. Checksums in data/raw/CHECKSUMS.
## What you need to know
Commune names arrive spelled four ways; normalisation is in src/clean.py and
must run before anything else.
La dernière section est celle qui épargne une semaine à un successeur. C’est la connaissance qui vit dans votre tête, et la leçon sur la passation porte sur la façon d’en sortir le reste.
Rapportez-le en entier
Analysis reproducibility
Raw exports are read-only under data/raw/ with SHA-256 checksums committed.
All cleaning, exclusion and recoding is in version-controlled code; no raw
file has been edited.
Every output in outputs/ is reproducible by `uv run python run.py` from a
clean checkout. Deleting outputs/ and rerunning leaves the repository
unchanged.
Dataset files are versioned by filename. The v1 file referenced by the
March report has not been modified; the correction ships as v2.
Le deuxième paragraphe est l’affirmation à faire et celle à tester avant de la faire. Elle se vérifie en une commande, et une analyse qui ne peut pas la passer devrait le dire plutôt que prétendre le contraire.
La suite
La gestion de versions est ce qui transforme « la seule chose éditée est le code » en un historique lisible. La leçon suivante porte sur l’emploi de git dans un travail d’analyse — et sur la seule chose qui ne doit jamais entrer dans un dépôt contenant des données de programme, parce que git est conçu pour ne jamais oublier.