Research Compendium ou comment bien ranger sa cuisine

Research Compendium

Research Compenkoi ?

Compendium



“A collection of concise but detailed information about a particular subject”



Un abrégé, un précis, un recueil.


Une archive qui synthétise de manière exhaustive votre projet d’analyse de données.

Research Compendium


  • Quelques règles simples pour organiser son répertoire de travail
  • Et pouvoir s’y retrouver (ou que les autres s’y retrouvent)
  • Partage du code, des données, des résultats. Avec vous-même, avec vos étudiants, vos encadrants, vos collègues ou le reste de la communauté scientifique.

Le problème “J’ai ma propre organisation”

Here enters …
le ‘Research Compendium’

Research compendium

le but ?

The goal of a research compendium is to provide a standard and easily recognisable way for organising the digital materials of a project to enable others to inspect, reproduce, and extend the research.

Three Generic Principles

  1. Organize its files according to prevailing conventions: i) help other people recognize the structure of the project, ii) supports tool building which takes advantage of the shared structure.
  1. Separate of data, method, and output, while making the relationship between them clear.
  1. Specify the computational environment that was used for the original analysis.

Organisation (projets)

Utilisez les projets RStudio

Travaillez selon le modèle : “1 projet = 1 compendium = 1 répertoire”.

L’utilisation d’un projet RStudio permet de se retrouver à la racine du projet à son ouverture.

    │
    ├── [my_project]
    │   └── my_project.Rproj
    │
    ├── [another_project]
    │   └── another_project.Rproj
    │
    ├── [again_another_project]
    │   └── again_another_project.Rproj
    │

Organisation (projets)

Organisation (projets)

Stop à setwd() !!

Les chemins absolus (e.g. C:\\Albert\Bureau\PhD) ne fonctionnent que (temporairement) chez vous et jamais chez les autres.

Tous les chemins seront relatifs et définis à partir de la racine du projet : e.g. outputs/01_datacleaned.csv, data/data_raw.csv

Organisation (projets)


Utilisez le package {here}

dans vos rapports (quarto, Rmarkdown) pour laisser le code recréer les chemins absolus :

# bad !
setwd("good/luck/where/my_project/is/data")
dat <- read.csv("data_raw.csv")]

Organisation (projets)


Utilisez le package {here}

dans vos rapports (quarto, Rmarkdown) pour laisser le code recréer les chemins absolus :

# bad !
# setwd("good/luck/where/my_project/is/data")
# dat <- read.csv("data_raw.csv")]

# better
dat_path <- file.path("data", "data_raw.csv")
dat <- read.csv(here::here(dat_path))

Separation of data, method, and output


This means data files must be separate from code files.


And that output files are separated too.

Separation of data, method, and output


La séparation entre données et résultats est matérialisée par des répertoires.

    .
    ├── my_project.Rproj
    ├── [data]
    └── [outputs]

Separation of data, method, and output


La séparation entre données et résultats est matérialisée par des répertoires.

    .
    ├── my_project.Rproj
    ├── [data] (données brutes)
    └── [outputs] (résultats)

Separation of data, method, and output


La séparation entre données et résultats est matérialisée par des répertoires.

    .
    ├── my_project.Rproj
    ├── [data] (données brutes)
    └── [outputs] (résultats)

Implications

Keeping data and method separate treats the data as “read-only”, so that the original data is untouched and all modifications are transparently documented in the code.

The output files should be considered as disposable, with a mindset that one can always easily regenerate the output using the code and data.

Separation of data, method, and output


Stop à rm(list=ls()) !!

Les résultats sont “refabricables”.

Separation of data, method, and output


Le code (les méthodes) est factorisé en morceaux réutilisables (des fonctions), elle sont appellées par les scripts d’analyses :

    .
    ├── my_project.Rproj
    ├── [data] (données brutes)
    ├── [R] (fonctions = morceaux de code réutilisables)
    ├── [analyses] (les scripts)
    └── [outputs] (résultats)

Separation of data, method, and output


Le code (les méthodes) est factorisé en morceaux réutilisables (des fonctions), elle sont appellées par les scripts d’analyses :

    .
    ├── my_project.Rproj
    ├── [data]
    ├── [R]
    ├── [analyses]
    └── [outputs]

Attention à R

Attention le répertoire R ne doit contenir que des fichiers .R qui ne contiennent que des définitions de fonctions !

Car tout code présent dans R sera executé lors d’un appel aux fonctions devtools::load_all() ou targets::tar_source(), bien utiles par ailleurs !

Separation of data, method, and output


    .
    ├── my_project.Rproj
    ├── [data]
    ├── [R]
    ├── [analyses]
    └── [outputs]
    .
    ├── my_project.Rproj
    ├── [data]
    │   ├── [raw_data]
    │   └── [derived_data]
    ├── [R]
    ├── [analyses]
    ├── [figures]
    └── [outputs]

Fléxibilité

Il existe des modèles d’organisation plus ou moins complexes, on adaptera la compléxité du compendium à celle du projet.

Principes

  • Le flux d’analyses doit être séparé en étapes courtes (ou pas trop longues) et homogènes
  • Numérotez les scripts, placez-y des entêtes
.
├── my_project.Rproj
├── [data]
├── [R]
├── [analyses]
│   ├── 00_setup.R (chargement des packages, variables globales)
│   ├── 01_data.R (lecture et formatage des données)
│   ├── 02_length-weight.R (première étape d'analyse)
│   ├── 03_plot-length-weight.R (génération du premier plot)
│   ├── ...
└── [outputs]

Principes

  • Le flux d’analyses doit être séparé en étapes courtes (ou pas trop longues) et homogènes
  • Numérotez les scripts, placez-y des entêtes
############################################################
#
# 00_setup.R: load packages, set global variables
#
############################################################

Principes

  • The relationship between which code operates on which data in which order to produce which outputs must be specified as well.

  • Utilisez un script “maître” (make.R) qui execute les étapes dans l’ordre (c’est le SEUL script R à la racine !)

.
├── my_project.Rproj
├── [data]
├── [R]
├── [analyses]
├── [outputs]
└── make.R

Principes

  • Utilisez un script “maître” (make.R) qui execute les étapes dans l’ordre (c’est le SEUL script R à la racine !)
############################################################
#
# make.R: build the project
#
############################################################

source("analyses/00_setup.R")

source("analyses/01_data.R")

source("analyses/02_length-weight.R")

source("analyses/03_plot-length-weight.R")

Principes

  • The relationship between which code operates on which data in which order to produce which outputs must be specified as well.

Chaque script (étape) écrit des résultats (fichiers) les référençant explicitement dans leur nom.

  • le script “analyses/01_data.R” écrit des résultats du type “outputs/01_length-weight_females.RData”
  • le script “analyses/03_plot-length-weight.R” écrit des résultats du type “figures/03_length-weight_males.png”

Limitation du modèle …

  • Il devient compliqué, lorsque l’analyse n’est pas linéaire et que les relations entre les étapes sont complexes, de se souvenir de toutes les dépendances entre scripts, données et résultats.

  • On est souvent ammener à relancer l’ensemble des analyses.

  • Et si les calculs sont longs, cela devient vraiment contre-productif !

Limitation du modèle …

Limitation du modèle …

  • Utilisez le package targets


Limitation du modèle …

  • Utilisez le package targets


.
├── my_project.Rproj
├── [data]
├── [R]
├── [analyses]
|   └── pipeline.R
├── [outputs]
└── make.R

Principes

  • Should specify the computational environment that was used for the original analysis.

At its most basic, this could be a plain text file that includes a short list of the names and version numbers of the software and other critical tools used for the analysis. In more complex approaches, described below, the computational environment can be automatically preserved or reproduced as well.

Principes

  • Should specify the computational environment that was used for the original analysis.

Placez un README à la racine du projet.

Écrivez-le en Rmd ou qmd, compilez le dans le make.R.

############################################################
#
# make.R: build the project
#
############################################################

[...]

source("analyses/03_plot-length-weight.R")

quarto::quarto_render("README.qmd", output_file = "README.md")
  .
  ├── my_project.Rproj
  ├── [data]
  ├── [R]
  ├── [analyses]
  ├── [outputs]
  ├── README.md
  ├── README.qmd
  └── make.R

Principes

  • Should specify the computational environment that was used for the original analysis.

Placez un README à la racine du projet.

Écrivez-le en Rmd ou qmd, compilez le dans le make.R.

############################################################
#
# make.R: build the project
#
############################################################

[...]

,tarchetypes::tar_quarto("README.qmd", output_file = "README.md")
)
  .
  ├── my_project.Rproj
  ├── [data]
  ├── [R]
  ├── [analyses]
  ├── [outputs]
  ├── README.md
  ├── README.qmd
  └── make.R

Principes

  • Should specify the computational environment that was used for the original analysis.

Utilisez le fichier DESCRIPTION et le package renv pour les packages !

.
├── DESCRIPTION
├── [data]
├── [R]
├── [analyses]
├── [outputs]
├── my_project.Rproj
├── README.md
├── README.qmd
├── renv.lock
└── make.R

Principes

  • Should specify the computational environment that was used for the original analysis.

Utilisez le fichier DESCRIPTION et le package renv pour les packages !

DESCRIPTION

Package: fish_length-weight_run
Type: Package
Title: Fish Length-Weight in la Réunion
Version: 0.0.0.9000

Imports: 
    ggplot2,
    qs

make.R

#renv::init()
renv::install()
renv::snapshot()

Principes

  • Should specify the computational environment that was used for the original analysis.

    Utilisez docker pour tout le reste (OS, librairies système) !

Principes

  • Séparons aussi le(s) documents de synthèse (papier, présentation, …)
.
├── DESCRIPTION
├── [data]
├── [R]
├── [analyses]
├── [outputs]
├── [syntheses]
├── my_project.Rproj
├── README.md
├── README.qmd
├── renv.lock
└── make.R

Principes

  • Séparons aussi le(s) documents de synthèse (papier, présentation, …)
.
├── DESCRIPTION
├── [data]
├── [R]
├── [analyses]
├── [outputs]
├── [syntheses]
|   ├── paper.qmd
|   └── presentation.qmd
├── my_project.Rproj
├── README.md
├── README.qmd
├── renv.lock
└── make.R

Utilisez le package quarto il est vraiment puissant.

Principes

  • Intégrons aussi les ressources utiles (biblio, etc …)
.
├── DESCRIPTION
├── [data]
├── [R]
├── [analyses]
├── [outputs]
├── [syntheses]
├── [documents]
├── my_project.Rproj
├── README.md
├── README.qmd
├── renv.lock
└── make.R

Diffusion / stockage

  • Il existe de nombreuses plateformes pour stocker votre supp. mat.

  • La plupat sont propriétaires/privées et/ou payantes (e.g. Dryad, https://datadryad.org/)

  • Il existe Zenodo (https://zenodo.org/) : Il a été créé par OpenAIRE et le CERN pour fournir aux chercheurs un lieu pour déposer des ensembles de données. Il a été lancé en 2013, permettant à des chercheurs de télécharger des fichiers jusqu’à 50 GO.

Diffusion / stockage

  • Il existe Zenodo (https://zenodo.org/) permettant de télécharger des fichiers jusqu’à 50 GO.


le package R

  • Finalement cette architecture n’est pas si différente de celle d’un package R !

  • En intégrant les éléments essentiels de la structure d’un package (DESCRIPTION, R/) on bénéficie de tous les outils développés dans ce contexte.

Outils de développement

devtools::load_all()

renv::install()

targets::tar_source()

usethis::use_[...]()

Research Compendium

    .
    ├── [data]
    |   └── raw-data.csv    
    ├── [R]
    |   └── functions.R
    ├── [analyses]
    |   └── pipeline.R
    ├── [outputs]
    ├── [syntheses]
    |   └── paper.qmd
    ├── [documents]
    ├── my_project.Rproj
    ├── README.md
    ├── DESCRIPTION
    ├── Dockerfile
    ├── renv.lock
    └── make.R

Research Compendium

    .
    ├── [data]
    |   └── raw-data.csv
    ├── [R]
    |   └── functions.R
    ├── [analyses]
    |   └── pipeline.R
    ├── [outputs]
    ├── [syntheses]
    |   └── paper.qmd
    ├── [documents]
    ├── my_project.Rproj (projet)
    ├── README.md
    ├── DESCRIPTION
    ├── Dockerfile
    ├── renv.lock
    └── make.R

Research Compendium

    .
    ├── [data]
    |   └── raw-data.csv (données brutes)
    ├── [R]
    |   └── functions.R (fonctions)
    ├── [analyses]
    |   └── pipeline.R (workflow)
    ├── [outputs] (résultats)
    ├── [syntheses]
    |   └── paper.qmd
    ├── [documents]
    ├── my_project.Rproj (projet)
    ├── README.md
    ├── DESCRIPTION
    ├── Dockerfile
    ├── renv.lock
    └── make.R (setup, workflow)

Research Compendium

    .
    ├── [data]
    |   └── raw-data.csv (données brutes)
    ├── [R]
    |   └── functions.R (fonctions)
    ├── [analyses]
    |   └── pipeline.R (workflow)
    ├── [outputs] (résultats)
    ├── [syntheses]
    |   └── paper.qmd
    ├── [documents]
    ├── my_project.Rproj (projet)
    ├── README.md
    ├── DESCRIPTION (dépendences, packages)
    ├── Dockerfile (dépendences, -> OS)
    ├── renv.lock (dépendences, packages)
    └── make.R (setup, workflow)

Research Compendium

    .
    ├── [data]
    |   └── raw-data.csv (données brutes)
    ├── [R]
    |   └── functions.R (fonctions)
    ├── [analyses]
    |   └── pipeline.R (workflow)
    ├── [outputs] (résultats)
    ├── [syntheses]
    |   └── paper.qmd (article, supp. mat, presentation)
    ├── [documents] (biblio)
    ├── my_project.Rproj (projet)
    ├── README.md
    ├── DESCRIPTION (dépendences, packages)
    ├── Dockerfile (dépendences, -> OS)
    ├── renv.lock (dépendences, packages)
    └── make.R (setup, workflow)

Research Compendium

    .
    ├── [data]
    |   └── raw-data.csv (données brutes)
    ├── [R]
    |   └── functions.R (fonctions)
    ├── [analyses]
    |   └── pipeline.R (workflow)
    ├── [outputs] (résultats)
    ├── [syntheses]
    |   └── paper.qmd (article, supp. mat, presentation)
    ├── [documents] (biblio)
    ├── my_project.Rproj (projet)
    ├── README.md (help)
    ├── DESCRIPTION (dépendences, packages)
    ├── Dockerfile (dépendences, -> OS)
    ├── renv.lock (dépendences, packages)
    └── make.R (setup, workflow)

Research compendium

    .
    ├── [data]
    |   └── raw-data.csv
    ├── [R]
    |   └── functions.R
    ├── [analyses]
    |   └── pipeline.R
    ├── [outputs]
    ├── [syntheses]
    |   └── paper.qmd
    ├── [documents]
    ├── my_project.Rproj
    ├── README.md
    ├── DESCRIPTION
    ├── Dockerfile
    ├── renv.lock
    └── make.R