- Qui ne s'est jamais retrouvé coincé entre deux projets R utilisant deux versions différentes d'un même package ?
- Qui n'a jamais eu cette idée folle, un jour d'inventer un cas d'école (via R) qu'il souhaitait partager ?
- Qui n'a jamais eu à chercher quelle version de package est nécessaire avec un code récupéré d'un collègue pour qu'il fonctionne comme celui du dit collègue ?
- Qui n'a jamais installé nombre de packages dans sa librairie pour divers projets et n'a jamais osé les désinstaller par peur que des projets ne fonctionnent plus ?
- Qui n'a jamais mis à jour un package dans un projet pour qu'il fonctionne, et ainsi cessé de faire fonctionner un autre projet ?
- Qui n'a jamais mis à jour par erreur un package et involontairement TOUTES ses dépendances avec la même conséquence que ci-dessus ?
Je vais m'arrêter là, je pense que vous avez compris que la gestion de packages sous R est une source d'erreurs faciles. Mais pas d'inquiétude :
Packrat fait tout ça , Packrat est simple, Packrat vous veut du bien !
Packrat ? Kézako ?
Packrat c'est un petit package R.
"Encore un ?!" vous allez me dire, oui mais il va vous simplifier la vie car il va rendre vos projets R :
- Indépendants : installer un nouveau package ou le mettre à jour dans votre projet ne va pas impacter tous vos autres projets R (qu'ils aient été développés avec packrat ou non)
- Portables : votre projet sera déplaçable/partageable d'un poste à un autre, et même d'un système d'exploitation à un autre (compilation différente vous me dites ? Kein problem fräulein ! / T'inquiète paupiette). Les installations des packages nécessaire à votre projet seront facilitées.
- Reproductibles : packrat vous crée une sorte de sandbox ("un bac à sable", ou "un environnement isolé" pour les puristes) que vous pouvez relancer n'importe où, n'importe quand pour retrouver votre projet comme vous l'aviez laissé (et donc exactement les mêmes réultats) ! Il vous sauvegarde votre environnement et vous le remet à disposition dès que demandé.
Mais ! Mais ! Pourquoi tu ne fais pas un environnement virtuel, une VM ?
Eh bien pour plusieurs raisons :
- Pas besoin de devoir connaître d'autres langages, outils logiciels. Connaître R suffit
- Actuellement, et à ma connaissance, il n'y a que Conda qui gère les environnements R
- Installer une VM pour un petit projet R c'est quand même sortir la mitrailleuse pour tuer un moustique
Comment ça marche ?
Si vous êtes comme la plupart des gens organisés (hep hep hep ! Revenez même si vous ne l'êtes pas), vous créez un répertoire pour chacun de vos nouveaux projets R où vous rangez tout vos scripts et vos sources (et si vous ne le faisiez pas, commencez). Eh bien Packrat, à son lancement, va se servir de ce répertoire pour en faire une sandbox avec votre librairie dédiée à l'intérieur et un ensemble de fichier et répertoires nécessaire pour exploiter correctement toutes les fonctionnalités :
- packrat/packrat.lock : liste de tous vos packages dans le projet avec leur version, les versions des dépendances, les versions des dépendances de dépendances, … Bref vous avez compris.
- packrat/packrat.opts : spécifique à l'environnement d'exécution de votre projet Packrat, il liste toutes les options que vous avez définies (voir les options disponibles plus bas)
- packrat/.Rprofile : indique à R d'utiliser la librairie interne au projet lorsqu'on lance celui-ci depuis le répertoire du projet
- packrat/lib/ : votre librairie interne (qui contient tout vos packages compilés à telle ou telle version et leurs dépendances compilées)
- packrat/src/ : les sources de vos packages et de leurs dépendances
Mais ! Mais ! Pourquoi tu t'embêtes à prendre tes sources si tu as déjà tes packages compilés ?
Et bien tout simplement pour la portabilité dont je vous parlais plus haut, je m'explique : Packrat créé un snapshot ("un instantané" pour les puristes) de l'état de votre librairie. Il sauvegarde alors les sources des packages utilisés et la versions de ceux-ci. Par la suite lors du transfert de votre projet Packrat de Windows à GNU/Linux ou autre, vous aurez simplement à lancer une commande qui restaurera votre librairie (en recompilant les sources de vos packages de façon compatible à votre OS) dans son état initial et vous voilà prêt à poursuivre votre travail !
Et en pratique on fait comment ?
En théorie on va lire la documentation[1], mais comme je suis sympa je vous aide.
1ère étape : installer Packrat
Pour ça rien de plus classique :
1 |
> ; install.packages("packrat") |
Note : dans le cas où vous souhaiteriez être dans la dernière version sortie (beta et donc pas totalement stable), vous pouvez également installer la dernière version du dépôt github :
1 2 |
> ; install.packages("devtools")<br> > ; devtools::install_github("rstudio/packrat") |
2ème étape : initialiser votre projet Packrat
Créez tout d'abord un répertoire selon le chemin[2] favori sur votre pc pour vos projets, puis dans R lancez :
1 |
> setwd("<leChemin>/PackratTest/")<br><br>> packrat::init(getwd())<br><br>Initializing packrat project in directory :<br>- "~/PackratTest"<br><br>Adding these packages to packrat :<br>_<br>packrat 0.4.6-1<br><br>Fetching sources for packrat (0.4.6-1) ... OK (CRAN current)<br>Snapshot written to "<leChemin>/PackratTest/packrat/packrat.lock"<br>Installing packrat (0.4.6-1) ...<br>OK (downloaded binary)<br>Initialization complete !<br><br>Restarting R session...<br><br>> packrat::on()<br>Packrat mode on. Using library in directory :<br>- "<leChemin>/PackratTest/packrat/lib" |
Félicitation, vous voilà dans un projet Packrat !
Mais ! Mais ! C'est nul ! Ça n'a rien changé ton truc !
Effectivement, pour le moment il n'y a pas de changement notable dans votre projet à part les fichiers que j'ai cités avant. La force de ce package se révèle quand on commence à jouer avec les packages !
3ème étape : ajouter, supprimer, mettre à jour des packages
Par curiosité, regardez votre dossier
1 |
< ;leChemin> ;/packrat/lib/ |
. Vous allez retrouver dedans votre sandbox compilée pour le système d'exploitation que vous utilisez, dans mon cas ce sera Windows comme vous pouvez le voir ci-dessous (rangez les couteaux à ce sujet, on trollera plus tard).
Vous trouverez dedans l'ensemble des packages que vous allez ajouter par la suite dans votre projet. Pour le moment seul packrat est présent, les packages que vous ajouterez par la suite viendront se ranger ici.
Appliquons maintenant cela à un cas pratique.
- Ajouter un package
Pour mon exemple je vais utiliser le package "e1071" (qui est utilisé pour la construction de modèles d'apprentissage supervisé de type Support Vecteur Machine ou SVM), mais n'importe lequel avec quelques dépendances ferait aussi bien l'affaire. Je débute donc classiquement par mon installation.
1 |
> install.packages("e1071", dependencies = TRUE)<br><br>also installing the dependencies ‘mlbench’, ‘randomForest’, ‘SparseM’, ‘xtable’<br><br>trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/mlbench_2.1–1.zip'<br>Content type 'application/zip' length 1032847 bytes (1008 KB)<br>downloaded 1008 KB<br><br>trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/randomForest_4.6–12.zip'<br>Content type 'application/zip' length 177253 bytes (173 KB)<br>downloaded 173 KB<br><br>trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/SparseM_1.76.zip'<br>Content type 'application/zip' length 928883 bytes (907 KB)<br>downloaded 907 KB<br><br>trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/xtable_1.8–2.zip'<br>Content type 'application/zip' length 710243 bytes (693 KB)<br>downloaded 693 KB<br><br>trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/e1071_1.6–8.zip'<br>Content type 'application/zip' length 800579 bytes (781 KB)<br>downloaded 781 KB<br><br>package ‘mlbench’ successfully unpacked and MD5 sums checked<br>package ‘randomForest’ successfully unpacked and MD5 sums checked<br>package ‘SparseM’ successfully unpacked and MD5 sums checked<br>package ‘xtable’ successfully unpacked and MD5 sums checked<br>package ‘e1071’ successfully unpacked and MD5 sums checked<br><br>The downloaded binary packages are in<br>< ;Chemin>\AppData\Local\Temp\RtmpIL8kez\downloaded_packages<br><br>> packrat::snapshot()<br><br>Adding these packages to packrat :<br>_<br>SparseM 1.76<br>e1071 1.6-8<br>mlbench 2.1-1<br>randomForest 4.6-12<br>xtable 1.8-2<br><br>Fetching sources for SparseM (1.76) ... OK (CRAN current)<br>Fetching sources for e1071 (1.6-8) ... OK (CRAN current)<br>Fetching sources for mlbench (2.1-1) ... OK (CRAN current)<br>Fetching sources for randomForest (4.6-12) ... OK (CRAN current)<br>Fetching sources for xtable (1.8-2) ... OK (CRAN current)<br>Snapshot written to "<leChemin>/PackratTest/packrat/packrat.lock"<br><br>> packrat::status()<br>Up to date. |
Comme vous pourrez le constater, e1071 n'est pas seul, il a ramené tous ses potes les dépendances avec lui comme on le lui a demandé ! Jetons maintenant un coup d’œil du côté de notre librairie packrat.
Tout les packages ont été installés et compilés pour notre OS courant. Et si on regarde du côté du dossier "src", on peut constater après la création du snapshot que les sources de chaque package ont été également téléchargées. On pourra donc aisément transporter notre projet et le recompiler pour un autre os au besoin.
1 |
Mais ! Mais ! Et si je veux ajouter des packages d'un dépôt externe à celui du CRAN ?
Pas de panique ! Vous ferez votre install.packages en précisant votre dépôt comme classiquement. Attention cependant à bien sélectionner la version source de votre packages, sans quoi vous vous retrouverez coincé pour l'exporter sur un OS différent.
Et si vous souhaitez directement ajouter un dépôt local, il existe une option qui le permet :
1 |
[crayon-67301050e62c3346716734 ]packrat::set_opts(local.repos = "path_to_repo") |
Prenez également garde dans ce cas à préciser un dépôt de packages source et non pas de packages compilés.
- Supprimer un package
Il arrive que vous installiez un package par erreur (de "alr3" à "alr4" il n'y a qu'un pas, de 1), vient donc le besoin de retirer ce package de votre snapshot jusqu'ici tout propre. On voudra par exemple supprimer un package nommé "nnet" et supposément installé précédemment (package qui crée également des modèles d'apprentissage supervisé mais cette fois de réseaux de neurones) mais qui ne vous convient pas pour vos données.
1 2 3 4 |
> ; remove.packages("xtable")<br> Removing package from ‘D :/Documents/PackratTest/packrat/lib/x86_64-w64-mingw32/3.2.1’<br> (as ‘lib’ is unspecified)<br> Et là c'est le drame, un collègue qui vous parle en même temps (sagouin !), une rêverie sur  ;votre futur prix Nobel, et vous supprimez le mauvais package (ici xtable) ! Regardons ce que nous raconte packrat pour nous consoler si on vérifie le statut de notre <em>snapshot</em>. |
1 |
> ; packrat::status() |
The following packages are tracked by packrat, but are no longer available in the local library nor present in your code :
_
xtable 1.8–2
You can call packrat::snapshot() to remove these packages from the lockfile, or if you intend to use these packages, use packrat::restore() to restore them to your private library.
Vous disposez donc d'une fonction de restauration de votre package perdu. Et si jamais vous souhaitiez réellement supprimer ce package, une mise à jour de votre snapshot permettra d'entériner cette décision (ce qui aura pour effet de supprimer la source dans le répertoire src).
Une astuce également intéressante pour la suppression de packages inutiles est de mettre simplement à jour de votre snapshot. Celui-ci en profite, si le cas se présente, pour vous signaler que certains des packages de votre librairie ne sont pas utilisés dans votre code. La commande clean vous permettra alors de supprimer ces packages devenus inutiles dans votre projet.
1 2 3 4 |
> ; packrat::status()<br> The following packages are installed but not needed :<br> _<br> nnet 7.3 |
Use packrat::clean() to remove them. Or, if they are actually needed by your
project, add
1 |
library(packagename) |
calls to a .R file somewhere in your project.
- Mettre à jour un package
De la même façon que vous installez un package, le besoin de mettre à jour un package se fera sûrement ressentir. Dans ce cas, effectuez votre mise à jour et pensez bien à faire un
1 |
packrat::snapshot  ; afin de bien informer packrat que ce package n'est pas un intrus ! |
Une bonne pratique à ce sujet est de toujours faire un
1 |
packrat::status  ; afin de vérifier l'impact de toute modification. |
Mais ! Mais ! Ça devient franchement casse bonbon de faire ça à chaque fois !
C'est là qu'interviennent les options packrat (notre petit packrat/packrat.opts du début). Vous pouvez notamment programmer un auto snapshot d'un habile packrat::set_opts(auto.snapshot = TRUE).
Il existe plusieurs autres options mais je vous laisse le soin de RTFM [1] ;D
4ème étape : partager, exporter cet environnement et le restaurer
Vos voici donc, après peaufinage par vos petits soins, avec votre environnement R au complet pour exécuter les scripts que vous devez passer à votre collègue qui bosse sous un autre OS (Ubuntu par exemple, tssss quelle idée je vous jure :p). Cependant une étape reste à faire : le bundling, ou "empaquetage" en français.
Pour cela, pas la peine de se casser la tête, une fonction existe encore une fois pour cela (même si on ne va pas se le cacher, c'est un simple gzip dans les grandes lignes) :
1 2 3 4 |
> ; packrat::bundle()<br> The packrat project has been bundled at :<br> - "<leChemin>\PackratTest\packrat\bundles/PackratTest-2017–03-21.tar.gz"<br> # Oui le mélange "/" et "\" c'est Windows, c'est cadeau … |
Et ainsi votre collègue tout content n'aura plus qu'à récupérer la jolie archive, installer Packrat, et à utiliser la fonction complémentaire à cette première pour récupérer un environnement à l'identique, à l'exception que les packages R auront été compilés pour son OS.
Pour conclure
Packrat se révèle être très pratique et rapide pour vos projets se servant majoritairement des packages du CRAN ou d'un dépôt extérieur. Mais on pourra lui reprocher le cas où c'est un package personnel que vous souhaitez joindre, il faut alors définir un dépôt local. Une autre limitation dans cette lignée sera le cas où les sources des packages sont absentes (oui oui même sur le serveur du CRAN), ce qui empêchera de restaurer/recompiler les sources pour un OS sans avoir passer par la case téléchargement.
Pour ceux qui aiment utiliser Rstudio, sachez qu'une version built-in existe pour vous donner un côté plus graphique à la gestion de votre environnement.
Enfin, si j'ai abordé ici la majorité des fonctionnalités de ce petit packages bien pratique, sachez qu'il reste quelques subtilités que je vous laisse découvrir par vous même en lisant la documentation qui est claire et concise (donc pas d'excuse, 4 pages ça se lit vite, zou zou !)
Références
[1] https://rstudio.github.io/packrat/ [2] https://www.youtube.com/watch?v=CLuOd8xMRRoMerci aux relecteurs Yoann M., Mathurin et Zazo0o pour leur temps et leur œil à l’affût !
Laisser un commentaire