Environnements Virtuels
Avancer dans la quête de la reproductibilité
Nous reprenons l’exemple de Paul et d’Eric sur la page qui présente l’exercice de la version collaborative
Eric aurait besoin de travailler sur un autre projet qui mobilise une version de sf plus récente que celle utilisé par Paul. Sachant qu’il n’a qu’une machine, il est obligé d’installer et de désinstaller la librairie en fonction du projet sur lequel il travaille car sinon le projet de Paul ne marche plus.
C’est à ce moment que renv prend tout son intérêt, il va permettre à Paul de travailler sur plusieurs projets à la fois, chacun utilisant potentiellement des packages dont les versions peuvent être différentes.
Paul se renseigne et décide de mettre en place une photo des packages nécessaire pour reproduire une partie de son environnement. En plus il n’y a plus d’ambiguité car les numéro de version sont fixés.
R & renv
Renv est avant tout un package qu’il faut installer pour pouvoir utiliser ces fonctionnalités.
A. Introduction
Le package renv
permet d’aller un peu plus loin que les informations de sessions, nous allons voir pourquoi.
Sur le site de la société Posit dont les salarié(e)s maintiennent ce package, trois grand avantages sont mis en avant :
Isolated: Installing a new or updated package for one project won’t break your other projects, and vice versa. That’s because renv gives each project its own private package library.
Portable: Easily transport your projects from one computer to another, even across different platforms. renv makes it easy to install the packages your project depends on.
Reproducible: renv records the exact package versions you depend on, and ensures those exact versions are the ones that get installed wherever you go.
Si il y a une chose à retenir de renv, c’est qu’il prend une photo de votre environnement à un instant t, et il stocke le résultat dans un fichier renv.lock
. Il s’agit de la liste quasi1 complète des dépendances logicielles avec la version de R utilisé, et le numéro de version.
Cette photo, vous pouvez la transmettre à un autre collègue, et à partir de celle-ci il peut essayer de se placer dans le même environnement que vous.
B. Première photo
La gestion des dépendances en utilisant le package renv
est déjà intégré à RStudio, vous pouvez l’activer directement en cochant une case lorsque vous créer un nouveau projet (Quarto, R, etc.).
Si vous n’utilisez pas RStudio, ou si comme nous vous voulez repartir d’un projet existant, ce n’est pas grave, vous pouvez l’installer comme n’importe quel autre package avec la commande :
install.packages("renv")
Et ensuite pour convertir votre projet pour une gestion avec renv, il suffit de lancer :
library(renv)
::init() renv
A ce moment là, R vous affiche pas mal d’information, et indique notamment les fichiers et les dossiers qu’il va modifier dans votre projet pour qu’il puisse fonctionner.
renv va créer :
- un dossier renv dans le répertoire projet
- un fichier
renv.lock
Nous basculons dans un environnement isolé, donc tous les packages qui vont être utilisés au sein de votre projet vont maintenant être stocké dans le répertoire renv
Les fichiers suivants vont également être modifiés :
- si vous utilisez le versionnement, votre
.gitignore
va être modifié pour ne pas être pollué par les librairies installés dans le dossier renv/ - le fichier RBuildignore
- le fichier .Rprofile
Si vous êtes d’accord avec tout çà, renv vous demande de valider par [y/N] dans la console.
Lorsque vous initialisez un environnement Renv dans votre projet, celui-ci va scanner l’ensemble de vos fichiers pour construire la liste des dépendances nécessaire à la bonne execution de votre projet. Cela peut prendre quelques secondes à quelques minutes en fonction de la taille du projet.
renv vous affiche ensuite la liste des dépendances qu’il a detecté sous forme de liste et il écrit toutes ces informations dans le fichie renv.lock
.
- Linking packages into the project library ... [118/118] Done!
The following package(s) will be updated in the lockfile:
# CRAN -----------------------------------------------------------------------
- askpass [* -> 1.1]
- base64enc [* -> 0.1-3]
- BH [* -> 1.81.0-1]
- brew [* -> 1.0-8]
- bslib [* -> 0.4.2]
- cachem [* -> 1.0.8]
- callr [* -> 3.7.3]
- class [* -> 7.3-20]
- classInt [* -> 0.4-9]
- cli [* -> 3.6.0]
- colorspace [* -> 2.1-0]
- commonmark [* -> 1.9.0]
- cpp11 [* -> 0.4.3]
- crayon [* -> 1.5.2]
- crosstalk [* -> 1.2.0]
- curl [* -> 5.0.0]
- DBI [* -> 1.1.3]
- digest [* -> 0.6.31]
- dplyr [* -> 1.0.10]
- DT [* -> 0.33]
- e1071 [* -> 1.7-13]
- ellipsis [* -> 0.3.2]
- evaluate [* -> 0.21]
- fansi [* -> 1.0.3]
- farver [* -> 2.1.1]
- fastmap [* -> 1.1.1]
- fontawesome [* -> 0.5.1
...
- Rcpp [* -> 1.0.10]
- RcppSimdJson [* -> 0.1.11]
- renv [* -> 1.1.4]
- rlang [* -> 1.1.1]
- rmarkdown [* -> 2.21]
- s2 [* -> 1.1.3]
- sass [* -> 0.4.6]
- satellite [* -> 1.0.4]
- scales [* -> 1.2.1]
- servr [* -> 0.27]
- sf [* -> 1.0-12]
- sfheaders [* -> 0.4.2]
- sp [* -> 1.6-0]
- stringi [* -> 1.7.12]
- stringr [* -> 1.5.0]
- svglite [* -> 2.1.1]
- sys [* -> 3.4.1]
- systemfonts [* -> 1.0.4]
- terra [* -> 1.7-29]
- tibble [* -> 3.1.8]
- tidygeocoder [* -> 1.0.6]
- tidyselect [* -> 1.2.0]
- tinytex [* -> 0.45]
- units [* -> 0.8-2]
- utf8 [* -> 1.2.2]
- uuid [* -> 1.1-0]
- vctrs [* -> 0.6.2]
- viridis [* -> 0.6.3]
- viridisLite [* -> 0.4.2]
- webshot [* -> 0.5.4]
- withr [* -> 2.5.0]
- wk [* -> 0.7.2]
- xfun [* -> 0.39]
- yaml [* -> 2.3.7]
The version of R recorded in the lockfile will be updated:
- R [* -> 4.2.2]
- Lockfile written to "~/SOSHS/mon_super_notebook_R-main/renv.lock".
La syntaxe est la suivante :
- sf [* -> 1.0-12]
Cela signifie que le package sf est passé de * (rien) à la version 1.0-12 dans le fichier renv.lock
La photo initiale est faite, si vous passez ce fichier à un de vos collègues, il a seulement quelques commandes à taper, et il pourra créer un environnement isolé similaire au votre.
En voyant la liste, déjà largement tronqué pour la lisibilité du document, vous devez surement vous dire … mais d’ou viennent toutes ces dépendances que je ne connais pas ?
Eh bien, c’est l’intérêt aussi de ce genre d’outil, il va rendre explicite toutes les dépendances, mais aussi les sous dépendances nécessaire à l’execution de votre projet.
C. Passe la photo à ton voisin
Nous pourrions passer directement le renv.lock à un collègue, qui pourrait reinstaller les packages avec renv::restore() à partir d’un nouveau projet vide contenant seulement le renv.lock.
Dans ce cas là,
- au premier appel de
renv::restore()
, il vous demande ce que vous voulez faire, tapez (1) pour réactiver le projet. - une fois celui-ci réactivé, refaite renv::restore(), il vous propose de reinstaller les packages.
- vous pouvez ensuite copier les fichiers et dossier dans le projet pour les compiler.
Ce déroulé partant de zéro est assez laborieux, donc le plus intéressant pour partager, c’est encore de s’appuyer sur la forge :)
Pour que les collègues puissent récupérer automatiquement la photo, il suffit de faire un git add, git commit, git push de ces fichiers :
- renv.lock
- .Rprofile
- renv/settings.json
- renv/activate.R
Lors de son prochain git pull
, et lorsque votre collègue va ouvrir le projet, RStudio va directement détecter, installer et charger renv
, puis télécharger les packages manquant. Autrement dit il vous met en situation d’environnement isolé automatiquement.
Il y a toutefois quelque conditions pour que cela marche à 100%, et c’est la d’ailleur la limite de ce type d’outils pour la reproductibilité :
- il vous faudra une version de R compatible car renv ne gère pas l’installation de R sur la machine
- il y a des dépendances systèmes qui viennent parfois en plus des dépendances logicielles, c’est par exemple le cas de la plupart des packages qui sont basé sur du spatial qui dépendent de gdal, geos, proj, etc. !
D. Mise à jour de la photo
Lorsque vous installez une nouvelle dépendance, ou que vous en mettez une à jour, vous devez faire un renv::snapshot()
pour prendre une nouvelle photo.
Par exemple, nous devons installer une nouvelle version plus à jour de plyr
:
> install.packages("plyr")
The following package(s) will be installed:
- plyr [1.8.9]
These packages will be installed into "~/SOSHS/mon_super_notebook_R-main/renv/library/R-4.2/x86_64-w64-mingw32".
Do you want to proceed? [Y/n]:
# Installing packages --------------------------------------------------------
- Installing plyr ... OK [installed binary and cached in 0.34s] Successfully installed 1 package in 0.41 seconds.
Les informations renvoyés par renv::status()
après l’installation indique qu’il y a un souci entre l’état des dépendances actuelle et celles enregistrées dans renv.lock
:
> renv::status()
The following package(s) are out of sync [lockfile != library]:
# CRAN -----------------------------------------------------------------------
- plyr [1.8.8 != 1.8.9]
See `?renv::status` for advice on resolving these issues.
On refait un renv::snaphot()
pour remettre à jour la photo :
> renv::snapshot()
The following package(s) will be updated in the lockfile:
# CRAN -----------------------------------------------------------------------
- plyr [1.8.8 -> 1.8.9]
Do you want to proceed? [Y/n]: Y
- Lockfile written to "~/SOSHS/mon_super_notebook_R-main/renv.lock".
Et voilà, il n’y a plus qu’à faire un git add
, un commit
et un git push
les fichiers mis à jour par renv, et aussi à dire à vos collègues de faire un git pull
!
Notes de bas de page
Nous verrons à la fin pourquoi il s’agit seulement d’une photo partielle.↩︎