Literate programming & notebook avec R

Optimiser le partage et la reproductibilité de son code

Analyse de données en programmation

La pratique d’un langage de programmation (libre et gratuit) pour l’analyse de données offre des perspectives intéressantes :

  • Permet d’étendre ses compétences et de gagner en polyvalence
  • Permet la réproductibilité de son travail d’analyse
  • Facilite le partage de son travail d’analyse
  • Permet de gagner en transparence

→ Cela Implique de nouvelles méthodes de travail :

  • Comment rendre mon travail intelligible pour mes collègues (et pour moi) ?
  • Comment archiver et assurer une certaine reproductibilité de mes scripts ?
  • Comment mettre à disposition du code source (et ses résultats) ?



  • I. Pratique du literate programming


  • II. Utilisation du format de publication notebook


  • III. Gestion, stockage et partage avec Git

Literate programming

La programmation lettrée est une approche de la programmation qui se veut différente du paradigme de programmation structurée.

« Nous devons changer notre attitude traditionnelle envers la construction des programmes : au lieu de considérer que notre tâche principale est de dire à un ordinateur ce qu’il doit faire, appliquons-nous plutôt à expliquer à des êtres humains ce que nous voulons que l’ordinateur fasse. (…)

Celui qui pratique la programmation lettrée peut être vu comme un essayiste, qui s’attache principalement à exposer son sujet dans un style visant à l’excellence. Tel un auteur, il choisit, avec soin, le dictionnaire à la main, les noms de ses variables et en explique la signification pour chacune d’elles. Il cherche donc à obtenir un programme compréhensible parce que ses concepts sont présentés dans le meilleur ordre possible. Pour cela, il utilise un mélange de méthodes formelles et informelles qui se complètent. »

D. Knuth, « Literate Programming », The Computer Journal, British Computer Society, vol. 27, no 2,‎ 1984, p. 97–111

Le paradigme de la programmation lettrée, pensé et mis en oeuvre par Donald Knuth (1977-78), s’éloigne dans son écriture de l’ordonnancement imposé par l’ordinateur, et à la place autorise les développeurs à utiliser un ordre imposé par la logique et le fil de leur pensée.

Quelques lignes de code…

library(ggplot2)
ggplot(data = iris, 
       aes(x = cut(Sepal.Length, breaks = c(min(Sepal.Length), 5, 6, 7, max(Sepal.Length)), 
                   include.lowest = TRUE, labels = c("Bas","Bas+","Haut","Haut+")))) +
  geom_bar() + xlab("") + ylab("") + ggtitle("Répartition par classe") +
  theme(plot.title = element_text(size=27), axis.text=element_text(size=19))

…En programmation lettrée

#-----------------------------------------------------------------
#            Représentation graphique 
#         de la répartition d'individus
#         discrétisés en quatre classes 
#
#                  H. Pecout
#               5 décembre 2022
#-----------------------------------------------------------------

## Discrétisation la variable Sepal.Length (données iris)

# Statistiques sur la série statistique 'Sepal.Length'
summary(iris$Sepal.Length)

# Histogramme de la distribution
hist(iris$Sepal.Length)

# Choix des bornes de classes (amplitude égale)
bornes_des_classes <- c(min(iris$Sepal.Length), 5, 6, 7, 
                        max(iris$Sepal.Length))

# Choix des noms de classes
nom_des_classes <- c("Trés petites","petites","grandes","Très grandes")

# Discrétisation de la variable 'Sepal.length'
iris$classe  <- cut(iris$Sepal.Length,
                    breaks = bornes_des_classes,
                    labels = nom_des_classes,
                    include.lowest = TRUE)

#---------------------------------------------------------------------

## Représentation de la distribution selon la discrétisation

# Bibliothèque pour la représentation graphique
library(ggplot2)

# Représentation graphique de la distribution
ggplot(data = iris, aes(x = classe)) +  # Choix des données et de la variable à représenter
  geom_bar() +  # Choix du type de représentation
  xlab("") +    # Suppression du nom de l'axe x
  ylab("") +    # Suppression du nom de l'axe y
  ggtitle("Répartition par classe") +  # Titre du graphique
  theme(plot.title = element_text(size=27),  # Taille de la police titre 
        axis.text=element_text(size=19))     # Taille des labels d'axe

Quel outil pour la PL ?

Il est possible de faire de la programmation lettrée dans n’importe quel type de document… Ce paradigme n’est pas lié à format ou à un outil. Mais il en existe tout de même un parfait pour mettre en oeuvre ce concept.

Le notebook permet de combiner du langage naturel et du langage de programmation, et d’interpréter les deux :

  • Mise en forme du texte
  • Exécution et/ou affichage du code


Les notebooks et la programmation lettrée sont apparus à la même période, celle de l’émergence du concept de recherche reproductible…

💻 70’s show

Les premiers notebooks

  • 1970 : Scratchpad (Axiom)
  • 1987 : MathCad
  • 1988 : Mathematica
  • 1989 : Maple
  • 2011 : IPython

Émergence de la recherche reproductible

Jon Claerbout est l’un des premiers chercheur à exprimer le fait que les méthodes de calcul menacent la reproductibilité de la recherche si l’on ne donne pas un accès libre aux données et aux logiciels qui sous-tendent.

En 1976, il publie un ouvrage référence en traitement de signal :
« Fundamentals of Geophysical Data Processing »

Cette 1ère version - non-reproductible - sera le début d’un long travail de recherche sur la reproductibilité… Via des notebooks !


Émergence du Literate Programming

Le concept de programmation lettrée est pensé et conçu par Donald Knuth (1977-78). Le notebook se présente comme un outil idéal pour mettre en œuvre ce paradigme.

Définition

Interface de programmation qui permet de combiner des sections en langage naturel et des sections en langage informatique.

De nombreuses dénominations existent :

  • Article exécutable
  • Document computationnel
  • Document électronique interactif
  • Cahiers de programmation
  • Cahier électronique d’analyse
  • Calepin électronique
  • Carnet de code
  • Manifeste algorithmique
  • Notebook !

Un outil… des pratiques !

La mise en forme du texte se fait à l’aide d’un langage de balisage (Markdown, html…)

Anatomie d’un notebook

Un simple fichier texte (.rmd, .qmd, .ipynb…)

\

### Le Markdown

Markdown est un **langage de balisage léger** créé en 2004 par 
[John Gruber](https://fr.wikipedia.org/wiki/John_Gruber), 
avec l'aide d'[Aaron Swartz](https://fr.wikipedia.org/wiki/Aaron_Swartz), 
dans le but d'offrir une **syntaxe facile à lire et à écrire**. 

![](https://upload.wikimedia.org/wikipedia/commons/6/64/John_Gruber%2C_2009_%28cropped%29.jpg)
**John Gruber, 2004 : **

> « *Un document balisé par Markdown peut être lu en l'état sans donner 
l’impression d'avoir été balisé ou formaté par des instructions particulières.* »

Un document balisé par Markdown peut être converti en :   

>- HTML  
>- PDF  
>- plein d'autres formats[^1]   

[^1]: Un markdown peut également être converti en format word, LaTeX, ePub, odt...

\

#### Insérer du code ?

~~~R
library(ggplot2)
ggplot(data = iris, 
       aes(x = cut(Sepal.Length, breaks = c(min(Sepal.Length), 5, 6, 7, max(Sepal.Length)), 
                   include.lowest = TRUE, labels = c("Bas","Bas+","Haut","Haut+")))) +
  geom_bar() + 
  xlab("") + 
  ylab("") + 
  ggtitle("Répartition par classe") +
  theme(plot.title = element_text(size=27), axis.text=element_text(size=19))
~~~


Le Markdown

Markdown est un langage de balisage léger créé en 2004 par John Gruber, avec l’aide d’Aaron Swartz, dans le but d’offrir une syntaxe facile à lire et à écrire.

John Gruber, 2004 :

« Un document balisé par Markdown peut être lu en l’état sans donner l’impression d’avoir été balisé ou formaté par des instructions particulières. »

Un document balisé par Markdown peut être converti en :

  • HTML
  • PDF
  • plein d’autres formats1


Insérer du code ?

library(ggplot2)
ggplot(data = iris, 
       aes(x = cut(Sepal.Length, breaks = c(min(Sepal.Length), 5, 6, 7, max(Sepal.Length)), 
                   include.lowest = TRUE, labels = c("Bas","Bas+","Haut","Haut+")))) +
  geom_bar() + 
  xlab("") + 
  ylab("") + 
  ggtitle("Répartition par classe") +
  theme(plot.title = element_text(size=27), axis.text=element_text(size=19))

Les notebooks en SHS

2022, l’année

Nombreux usages & formats

Equivalent LaTeX + programmation :

  • Bibliographie, TOC, note de bas de page…
  • Feuille de style CSS
  • Et bien plus… Quarto !

 

Un format de publication
scientifique légitime !

Nombreux templates,
multiples usages :

  • Article

  • Manuel

  • Rapports

  • Livre

  • Tutoriel

  • Cours - Exercice

  • Blog - Site web

  • curriculum vitae

  • Diaporama

Programmation lettrée, notebook et reproductibilité

Programmation lettrée + Notebook = 🔥

Programmation lettrée

Notebook

Programmation lettrée + Notebook = 🔥


Reproductibilité ?

PL + NB + … ? = reproductibilité

Programmation lettrée

Notebook

Informations de session
et d’environnement

Mise à disposition
Conditions d’utilisation

PL + NB + … ? = reproductibilité

Quel outil pour le partage ?


GitLab ou GitHub (Git)

Git est un système de gestion de version distribué pour :

  • tracker les changements dans les fichiers texte
  • gérer l’historique du code source
  • partager le code dans des dépots distants

GitLab et GitHub sont des services web d’hébergement et de gestion de version (issue tracker, collaboration, hébergement web, CI/CD), qui reposent sur le logiciel de version Git

Notebook + GitLab (ou GitHub) = 🔥🔥

  • Les sources des notebooks sont de simples fichiers texte

➡️ Suivi des modifications (commit, branches, etc.) 
➡️ Partage et mise à disposition des fichiers sources (dépôt public ou privé)


  • GitLab et GitHub permettent de compiler un notebook

➡️ Continuous Integration


  • Ils permettent de déployer sur le web un notebook compilé en HTML

➡️ Continuous Deployment

Exemple

Ceci est un notebook !

Un peu de code :

##------------------------ PACKAGES utilisés --------------------------## 

# install.packages("sf")
# install.packages("leaflet")

# Chargement des librairies
library(sf)
library(leaflet)



##----------------- Création d'un objet sf (point) --------------------## 

# Cordonnées de l'Institut régional de Santé, Ouidah (Bénin)
lat = 6.349879282633317
lng = 2.0875418515099504

# Création d'un point
ptsfg <- st_point(c(lng, lat)) 

# Ajout du système géographique de référence
ptsfc <- st_sfc(ptsfg, crs = (4326))

# Création de l'attribut "name"
ptdf <- data.frame(id= 1, name = "Institut régional de Santé")

# Création de l'objet sf ponctuel
Here <- st_sf(ptdf,geometry = ptsfc)



##--------------------- Création carte dynamique ----------------------## 

# Lien vers une photo de l'IRSP
file <- 'https://www.centrelogivac.org/wp-content/uploads/2021/09/DJI_0084-450x253.jpg'

# Construction du marker
icons <- awesomeIcons(icon = 'ios-people',
                      iconColor = 'white',
                      library = 'ion',
                      markerColor = 'blue')


# Affichage du point - carte interactive
mamap <- leaflet(Here) %>%
            setView( lat = lat + 12, lng = lng, zoom = 3) %>% 
            addProviderTiles("GeoportailFrance.orthos") %>%
            addAwesomeMarkers(icon = icons,
                              popup = paste("<img src =", file, ">", 
                                            "<p style='text-align:center;'>Institut Régional</br>de Santé Publique</br>Comlan Alfred Quenum</a></p>"))

Ceci est un notebook !

Affichage du résultat :

Ceci est un notebook !


Quarto - Format Revealjs presentations :

Code source (GitHub) : https://github.com/EE-CIST/OUT1_NotebookR
Document compilé (Github) : https://ee-cist.github.io/OUT1_NotebookR/


Conditions d’utilisation :

Code source : Licence MIT
Diaporama : CC BY-SA 4.0


Informations session :

R version 4.2.1 (2022-06-23 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 22000)

Matrix products: default

locale:
[1] LC_COLLATE=French_France.utf8  LC_CTYPE=French_France.utf8   
[3] LC_MONETARY=French_France.utf8 LC_NUMERIC=C                  
[5] LC_TIME=French_France.utf8    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] leaflet_2.1.1 sf_1.0-7      ggplot2_3.3.6

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.9              pillar_1.7.0            compiler_4.2.1         
 [4] class_7.3-20            tools_4.2.1             digest_0.6.29          
 [7] jsonlite_1.8.0          evaluate_0.15           lifecycle_1.0.3        
[10] tibble_3.1.7            gtable_0.3.0            pkgconfig_2.0.3        
[13] rlang_1.0.6             cli_3.6.0               DBI_1.1.3              
[16] rstudioapi_0.13         crosstalk_1.2.0         yaml_2.3.5             
[19] xfun_0.31               fastmap_1.1.0           e1071_1.7-11           
[22] withr_2.5.0             stringr_1.5.0           dplyr_1.0.9            
[25] knitr_1.39              leaflet.providers_1.9.0 htmlwidgets_1.5.4      
[28] generics_0.1.3          vctrs_0.5.1             classInt_0.4-7         
[31] grid_4.2.1              tidyselect_1.1.2        glue_1.6.2             
[34] R6_2.5.1                fansi_1.0.3             rmarkdown_2.14         
[37] farver_2.1.1            purrr_0.3.4             magrittr_2.0.3         
[40] units_0.8-0             scales_1.2.0            ellipsis_0.3.2         
[43] htmltools_0.5.2         assertthat_0.2.1        colorspace_2.0-3       
[46] labeling_0.4.2          KernSmooth_2.23-20      utf8_1.2.2             
[49] proxy_0.4-27            stringi_1.7.12          munsell_0.5.0          
[52] crayon_1.5.1           

Exemples divers

Atelier partique avec Rmarkdown ?