Accueil > Généralités techniques > Un travail doit être reproductible.

Un travail doit être reproductible.

samedi 13 novembre 2021, par Philippe MICHEL

Vous réouvrez un travail réalisé il y a quelques semaines, vous refaites un calcul & ne trouvez plus le même résultat. Une situation qui peut paraître bizarre mais qui demeure très fréquente. Où on vous signale une erreur, mais où ? Comment la retrouver sans refaire tout le travail ? Pour en finir avec l’introduction chaque langage a des outils adaptés, je ne parlerai ici que de R & de LaTeX, bien entendu.

Tout travail scientifique doit pouvoir être reproduit. c’est une base. Dans un article le chapitre "Matériel & Méthode" doit permettre au lecteur de reproduire la manip décrite & c’est pareil pour tout travail que vous réalisez même s’il n’y a que vous qui devrez, peut-être, le refaire. Tout ce qui suit va vous paraître lourd, complexe & contraignant mais, à l’usage, que de temps gagné ! De plus le document généré, un peu lourd & indigeste peut néanmoins facilement servir de base pour rédiger le rapport final qui sera remis au client/collègue.

Reprendre un travail un peu ancien (quelques semaines), rouvrir un document & avoir tout son code, les explications, le pourquoi & les résultats, quel confort ! Il faut avoir connu les soirées à essayer de comprendre pourquoi les résultats fièrement annoncés ne sortent plus, que plus aucun chiffre ne colle... (expérience vécue).

Pour vous former à cette discipline un MOOC très bien fait est disponible sur FUN.

Les outils

Il existe des outils pour toutes les situations, tous les langages. je vais me limiter à ce que je connais , à savoir R. Et le choix dépend de l’IDE utilisé :

  • Pour RStudio ce sera [**Rmarkdown*], un dérivé de markdown qui permet d’y incorporer du code (R mais aussi Python etc.). très bien intégré, simple d’emploi.
  • Pour les vrais, les poilus qui se déforment les doigts sur Emacs, il y a [**org-mode*] votre vie en texte brut.
  • Sinon il y a toujours knitr qui sort du LaTeX mais plus lourd que les deux précédents.

Pour ma part, j’ai longtemps utilisé Emacs & org-mode. Mais depuis quelques mois je n’utilise plus que Rstudio & Rmarkdown. Plus simple.

Les principes

L’idée est de garder tout son code, (le bon, celui qui marche), les commentaires & les résultats sur un document unique qui se génère tout seul, enfin presque.

Configuration pour Emacs

Vous avez donc Emacs avec le package org-mode installé. Il va falloir configurer tout ça pour que org reconnaisse du code R (ou autre) & l’interprète. Pour la syntaxe org-mode voir le site officiel. On rajoute donc dans son .emacs :

 
 (setq org-confirm-babel-evaluate nil) ;; Do not ask for confirmation all the time!! 
(org-babel-do-load-languages 'org-babel-load-languages '( (shell . t) (python . t) (R . t) (org . t) (makefile . t) )) 
(add-to-list 'org-structure-template-alist '("r" "#+begin_src R :results output :session *R* :exports both\n\n#+end_src" "<src lang=\"R\">\n\n</src>")) 
(add-to-list 'org-structure-template-alist '("R" "#+begin_src R :results output graphics :file (org-babel-temp-file \"figure\" \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(add-to-list 'org-structure-template-alist '("RR" "#+begin_src R :results output graphics :file (org-babel-temp-file (concat (file-name-directory (or load-file-name buffer-file-name)) \"figure-\") \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(global-set-key (kbd "C-c S-t") 'org-babel-execute-subtree)
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)
(add-hook 'org-mode-hook 'org-display-inline-images)
(add-hook 'org-mode-hook 'org-babel-result-hide-all) (add-hook 'after-init-hook 'global-company-mode)  

On crée un document org-mode : C-x C-f exemple.org. Dans ce document on va insérer des zones de code (ou chunck par <r Tab qui va créer : #+begin_src R :results output :session *R* :exports both #+end_src On écrit son code R dans ce chunck, le texte explicatif autour & on lance la sortie en html via C-c C-e h o On peut aussi exporter en LaTeX ou en texte brut mais en cours de travail l’export html est le plus souple. l’export LaTeX est parfois capricieux, digère mal les erreurs. On aura donc une page web avec le bla-bla, le code & les résultats. Donc on écrit son code, on fait des erreurs, on corrige, on recommence & quand une portion est ok, on la copie dans sa page org. Un chunck doit être court, ne faire qu’une chose. Et le premier, en haut de page, doit ouvrir les packages utiles &, petit conseil, commencer par un sessionInfo() qui va indiquer le système, les versions utilisées etc.

RMarkdown

Pour l’utilisation de RMarkdown via Rstudio (on peut aussi l’utiliser via n’importe quel éditeur de texte, pourquoi pas Emacs) c’est beaucoup plus simple, tout est déjà prêt à l’emploi. Un petit clic sur "File/New File/Rmarkdown", la fenêtre de choix du modèle s’ouvre, on choisi "Document" puis le format du document final. Je vous conseille de travailler en html & d’exporter en PDF (via LaTeX) ou en .doc uniquement en final. L’export html est plus tolérant & bloque moins souvent. Le document proposé comprend une trame simple pour l’exemple. Bon début pour faire vos premiers pas, mais ensuite il vous faudra la remplacer par votre préambule perso. attention aux indentations ! le moindre espace en trop ou manquant entraîne une erreur ! Pour l’exemple voici le mien :

---
title: "COVID-19"
subtitle: "Hospitalisations"
author: "Philippe MICHEL"
date: "`r Sys.Date()`"
output:
 prettydoc::html_pretty:
   theme: architect
   highlight: github
   toc: yes
 html_document:
   df_print: paged
   toc: yes
   toc_float: true
   theme: lumen
   anchor_sections: TRUE
 html_notebook:
   fig_caption: yes
   theme: spacelab
 pdf_document:
   includes:
     in_header: tete.tex
   keep_tex: yes
   latex_engine: lualatex
   toc: yes  
editor_options:
 chunk_output_type: console
---

Premier chunck qui défini l’export. En commentant une ligne ou l’autre on passe d’une sortie complète (en décommettant aussi sessioninfo()) à un document simple qui peut être envoyé au donneur d’ordre.
```

  1. {r setup, include= FALSE}
  2. knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE, cache = TRUE)
  3. knitr::opts_chunk$set(echo = TRUE, warning = TRUE, message = TRUE) # sessionInfo()
  4. ```

Télécharger

Liste des packages utilisés

  1. ```{r info}
  2. rm(list=ls()) # On remet tout à zéro
  3. library("dplyr") l... # Tous les packages utilisés
  4. ```

Télécharger

Avec un modèle préfait vous gagnerez un temps fou.

Pour aller plus loin...