Accessibility Tools

- Le blog participatif de bioinformatique francophone depuis 2012 -

  • Qui ne s'est jamais retrou­vé coin­cé entre deux pro­jets R uti­li­sant deux ver­sions dif­fé­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 sou­hai­tait par­ta­ger ?
  • Qui n'a jamais eu à cher­cher quelle ver­sion de package est néces­saire avec un code récu­pé­ré d'un col­lègue pour qu'il fonc­tionne comme celui du dit col­lègue ?
  • Qui n'a jamais ins­tal­lé nombre de packages dans sa librai­rie pour divers pro­jets et n'a jamais osé les dés­ins­tal­ler par peur que des pro­jets ne fonc­tionnent plus ?
  • Qui n'a jamais mis à jour un package dans un pro­jet pour qu'il fonc­tionne, et ain­si ces­sé de faire fonc­tion­ner un autre pro­jet ?
  • Qui n'a jamais mis à jour par erreur un package et invo­lon­tai­re­ment TOUTES ses dépen­dances avec la même consé­quence que ci-des­sus ?

Je vais m'arrêter là, je pense que vous avez com­pris que la ges­tion 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 c'est aus­si un joli petit rat des bois
Cré­dit : Cali­for­nia Depart­ment of Fish and Wild­life - https://​flic​.kr/​p​/​A​U​B​cSL

Packrat ? Kézako ?

Packrat c'est un petit package R.

"Encore un ?!" vous allez me dire, oui mais il va vous sim­pli­fier la vie car il va rendre vos pro­jets R :

  • Indé­pen­dants : ins­tal­ler un nou­veau package ou le mettre à jour dans votre pro­jet ne va pas impac­ter tous vos autres pro­jets R (qu'ils aient été déve­lop­pés avec packrat ou non)
  • Por­tables : votre pro­jet sera déplaçable/​partageable d'un poste à un autre, et même d'un sys­tème d'exploitation à un autre (com­pi­la­tion dif­fé­rente vous me dites ? Kein pro­blem fräu­lein ! /​ T'inquiète pau­piette). Les ins­tal­la­tions des packages néces­saire à votre pro­jet seront faci­li­tées.
  • Repro­duc­tibles : packrat vous crée une sorte de sand­box ("un bac à sable", ou "un envi­ron­ne­ment iso­lé" pour les puristes) que vous pou­vez relan­cer n'importe où, n'importe quand pour retrou­ver votre pro­jet comme vous l'aviez lais­sé (et donc exac­te­ment les mêmes réul­tats) ! Il vous sau­ve­garde votre envi­ron­ne­ment et vous le remet à dis­po­si­tion dès que deman­dé.

Mais ! Mais ! Pour­quoi tu ne fais pas un envi­ron­ne­ment vir­tuel, une VM ?

Eh bien pour plu­sieurs rai­sons :

  • Pas besoin de devoir connaître d'autres lan­gages, outils logi­ciels. Connaître R suf­fit
  • Actuel­le­ment, et à ma connais­sance, il n'y a que Conda qui gère les envi­ron­ne­ments R
  • Ins­tal­ler une VM pour un petit pro­jet R c'est quand même sor­tir la mitrailleuse pour tuer un mous­tique

Comment ça marche ?

Si vous êtes comme la plu­part des gens orga­ni­sés (hep hep hep ! Reve­nez même si vous ne l'êtes pas), vous créez un réper­toire pour cha­cun de vos nou­veaux pro­jets R où vous ran­gez tout vos scripts et vos sources (et si vous ne le fai­siez pas, com­men­cez). Eh bien Packrat, à son lan­ce­ment, va se ser­vir de ce réper­toire pour en faire une sand­box avec votre librai­rie dédiée à l'intérieur et un ensemble de fichier et réper­toires néces­saire pour exploi­ter cor­rec­te­ment toutes les fonc­tion­na­li­tés :

  • packrat/packrat.lock : liste de tous vos packages dans le pro­jet avec leur ver­sion, les ver­sions des dépen­dances, les ver­sions des dépen­dances de dépen­dances, … Bref vous avez com­pris.
  • packrat/packrat.opts : spé­ci­fique à l'environnement d'exécution de votre pro­jet Packrat, il liste toutes les options que vous avez défi­nies (voir les options dis­po­nibles plus bas)
  • packrat/.Rprofile : indique à R d'utiliser la librai­rie interne au pro­jet lorsqu'on lance celui-ci depuis le réper­toire du pro­jet
  • packrat/​lib/​ : votre librai­rie interne (qui contient tout vos packages com­pi­lés à telle ou telle ver­sion et leurs dépen­dances com­pi­lées)
  • packrat/​src/​ : les sources de vos packages et de leurs dépen­dances

Mais ! Mais ! Pour­quoi tu t'embêtes à prendre tes sources si tu as déjà tes packages com­pi­lés ?

Et bien tout sim­ple­ment pour la por­ta­bi­li­té dont je vous par­lais plus haut, je m'explique : Packrat créé un snap­shot ("un ins­tan­ta­né" pour les puristes) de l'état de votre librai­rie. Il sau­ve­garde alors les sources des packages uti­li­sés et la ver­sions de ceux-ci. Par la suite lors du trans­fert de votre pro­jet Packrat de Win­dows à GNU/​Linux ou autre, vous aurez sim­ple­ment à lan­cer une com­mande qui res­tau­re­ra votre librai­rie (en recom­pi­lant les sources de vos packages de façon com­pa­tible à votre OS) dans son état ini­tial et vous voi­là prêt à pour­suivre votre tra­vail !

Et en pratique on fait comment ?

En théo­rie on va lire la documentation[1], mais comme je suis sym­pa je vous aide.

1ère étape : installer Packrat

Pour ça rien de plus clas­sique :

> install.packages("packrat")

Note : dans le cas où vous sou­hai­te­riez être dans la der­nière ver­sion sor­tie (beta et donc pas tota­le­ment stable), vous pou­vez éga­le­ment ins­tal­ler la der­nière ver­sion du dépôt github :

> install.packages("devtools")
> devtools::install_github("rstudio/packrat")

2ème étape : initialiser votre projet Packrat

Créez tout d'abord un réper­toire selon le chemin[2] favo­ri sur votre pc pour vos pro­jets, puis dans R lan­cez :

> setwd("<leChemin>/PackratTest/")

> packrat::init(getwd())

Initializing packrat project in directory:
- "~/PackratTest"

Adding these packages to packrat:
_
packrat 0.4.6-1

Fetching sources for packrat (0.4.6-1) ... OK (CRAN current)
Snapshot written to "<leChemin>/PackratTest/packrat/packrat.lock"
Installing packrat (0.4.6-1) ...
OK (downloaded binary)
Initialization complete!

Restarting R session...

> packrat::on()
Packrat mode on. Using library in directory:
- "<leChemin>/PackratTest/packrat/lib"

Féli­ci­ta­tion, vous voi­là dans un pro­jet Packrat !

Mais ! Mais ! C'est nul ! Ça n'a rien chan­gé ton truc !

Effec­ti­ve­ment, pour le moment il n'y a pas de chan­ge­ment notable dans votre pro­jet à part les fichiers que j'ai cités avant. La force de ce package se révèle quand on com­mence à jouer avec les packages !

3ème étape : ajouter, supprimer, mettre à jour des packages

Par curio­si­té, regar­dez votre dos­sier

<leChemin>/packrat/lib/

 . Vous allez retrou­ver dedans votre sand­box com­pi­lée pour le sys­tème d'exploitation que vous uti­li­sez, dans mon cas ce sera Win­dows comme vous pou­vez le voir ci-des­sous (ran­gez les cou­teaux à ce sujet, on trol­le­ra plus tard).

État de mon dos­sier de pro­jet après une ini­tia­li­sa­tion d'un pro­jet packrat

Vous trou­ve­rez dedans l'ensemble des packages que vous allez ajou­ter par la suite dans votre pro­jet. Pour le moment seul packrat est pré­sent, les packages que vous ajou­te­rez par la suite vien­dront se ran­ger ici.

Appli­quons main­te­nant cela à un cas pra­tique.

  • Ajou­ter un package

Pour mon exemple je vais uti­li­ser le package "e1071" (qui est uti­li­sé pour la construc­tion de modèles d'apprentissage super­vi­sé de type Sup­port Vec­teur Machine ou SVM), mais n'importe lequel avec quelques dépen­dances ferait aus­si bien l'affaire. Je débute donc clas­si­que­ment par mon ins­tal­la­tion.

> install.packages("e1071", dependencies = TRUE)

also installing the dependencies ‘mlbench’, ‘randomForest’, ‘SparseM’, ‘xtable’

trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/mlbench_2.1-1.zip'
Content type 'application/zip' length 1032847 bytes (1008 KB)
downloaded 1008 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/randomForest_4.6-12.zip'
Content type 'application/zip' length 177253 bytes (173 KB)
downloaded 173 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/SparseM_1.76.zip'
Content type 'application/zip' length 928883 bytes (907 KB)
downloaded 907 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/xtable_1.8-2.zip'
Content type 'application/zip' length 710243 bytes (693 KB)
downloaded 693 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/e1071_1.6-8.zip'
Content type 'application/zip' length 800579 bytes (781 KB)
downloaded 781 KB

package ‘mlbench’ successfully unpacked and MD5 sums checked
package ‘randomForest’ successfully unpacked and MD5 sums checked
package ‘SparseM’ successfully unpacked and MD5 sums checked
package ‘xtable’ successfully unpacked and MD5 sums checked
package ‘e1071’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
<Chemin>\AppData\Local\Temp\RtmpIL8kez\downloaded_packages

> packrat::snapshot()

Adding these packages to packrat:
_
SparseM 1.76
e1071 1.6-8
mlbench 2.1-1
randomForest 4.6-12
xtable 1.8-2

Fetching sources for SparseM (1.76) ... OK (CRAN current)
Fetching sources for e1071 (1.6-8) ... OK (CRAN current)
Fetching sources for mlbench (2.1-1) ... OK (CRAN current)
Fetching sources for randomForest (4.6-12) ... OK (CRAN current)
Fetching sources for xtable (1.8-2) ... OK (CRAN current)
Snapshot written to "<leChemin>/PackratTest/packrat/packrat.lock"

> packrat::status()
Up to date.

Comme vous pour­rez le consta­ter, e1071 n'est pas seul, il a rame­né tous ses potes les dépen­dances avec lui comme on le lui a deman­dé ! Jetons main­te­nant un coup d’œil du côté de notre librai­rie packrat.

Réper­toire src après l'installation d'un package

Tout les packages ont été ins­tal­lés et com­pi­lés pour notre OS cou­rant. Et si on regarde du côté du dos­sier "src", on peut consta­ter après la créa­tion du snap­shot que les sources de chaque package ont été éga­le­ment télé­char­gées. On pour­ra donc aisé­ment trans­por­ter notre pro­jet et le recom­pi­ler pour un autre os au besoin.





Mais ! Mais ! Et si je veux ajou­ter des packages d'un dépôt externe à celui du CRAN ?

Pas de panique ! Vous ferez votre install.packages en pré­ci­sant votre dépôt comme clas­si­que­ment. Atten­tion cepen­dant à bien sélec­tion­ner la ver­sion source de votre packages, sans quoi vous vous retrou­ve­rez coin­cé pour l'exporter sur un OS dif­fé­rent.

Et si vous sou­hai­tez direc­te­ment ajou­ter un dépôt local, il existe une option qui le per­met :

packrat::set_opts(local.repos = "path_to_repo")

 Pre­nez éga­le­ment garde dans ce cas à pré­ci­ser un dépôt de packages source et non pas de packages com­pi­lés.

  • Sup­pri­mer un package

Il arrive que vous ins­tal­liez un package par erreur (de "alr3" à "alr4" il n'y a qu'un pas, de 1), vient donc le besoin de reti­rer ce package de votre snap­shot jusqu'ici tout propre. On vou­dra par exemple sup­pri­mer un package nom­mé "nnet" et sup­po­sé­ment ins­tal­lé pré­cé­dem­ment (package qui crée éga­le­ment des modèles d'apprentissage super­vi­sé mais cette fois de réseaux de neu­rones) mais qui ne vous convient pas pour vos don­nées.

> remove.packages("xtable")
Removing package from ‘D:/Documents/PackratTest/packrat/lib/x86_64-w64-mingw32/3.2.1’
(as ‘lib’ is unspecified)
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 snapshot.
> packrat::status()

The fol­lo­wing packages are tra­cked by packrat, but are no lon­ger avai­lable in the local libra­ry nor present in your code :
_​
xtable 1.8-2

You can call packrat::snapshot() to remove these packages from the lock­file, or if you intend to use these packages, use packrat::restore() to res­tore them to your pri­vate libra­ry.
Vous dis­po­sez donc d'une fonc­tion de res­tau­ra­tion de votre package per­du. Et si jamais vous sou­hai­tiez réel­le­ment sup­pri­mer ce package, une mise à jour de votre snap­shot per­met­tra d'entériner cette déci­sion (ce qui aura pour effet de sup­pri­mer la source dans le réper­toire src).

Une astuce éga­le­ment inté­res­sante pour la sup­pres­sion de packages inutiles est de mettre sim­ple­ment à jour de votre snap­shot. Celui-ci en pro­fite, si le cas se pré­sente, pour vous signa­ler que cer­tains des packages de votre librai­rie ne sont pas uti­li­sés dans votre code. La com­mande clean vous per­met­tra alors de sup­pri­mer ces packages deve­nus inutiles dans votre pro­jet.

> packrat::status()
The following packages are installed but not needed:
_
nnet 7.3

Use packrat::clean() to remove them. Or, if they are actual­ly nee­ded by your
pro­ject, add

calls to a .R file somew­here in your pro­ject.

  • Mettre à jour un package

De la même façon que vous ins­tal­lez un package, le besoin de mettre à jour un package se fera sûre­ment res­sen­tir. Dans ce cas, effec­tuez votre mise à jour et pen­sez bien à faire un

packrat::snapshot  afin de bien informer packrat que ce package n'est pas un intrus !

Une bonne pra­tique à ce sujet est de tou­jours faire un

packrat::status  afin de vérifier l'impact de toute modification.

Mais ! Mais ! Ça devient fran­che­ment casse bon­bon de faire ça à chaque fois !

C'est là qu'interviennent les options packrat (notre petit packrat/packrat.opts du début). Vous pou­vez notam­ment pro­gram­mer un auto snap­shot d'un habile packrat::set_opts(auto.snapshot = TRUE).

Il existe plu­sieurs autres options mais je vous laisse le soin de RTFM [1] ;D

RTFM - xkcd - https://​xkcd​.com/​2​93/

4ème étape : partager, exporter cet environnement et le restaurer

Vos voi­ci donc, après peau­fi­nage par vos petits soins, avec votre envi­ron­ne­ment R au com­plet pour exé­cu­ter les scripts que vous devez pas­ser à votre col­lègue qui bosse sous un autre OS (Ubun­tu par exemple, tssss quelle idée je vous jure :p). Cepen­dant une étape reste à faire : le bund­ling, ou "empa­que­tage" en fran­çais.

Pour cela, pas la peine de se cas­ser la tête, une fonc­tion 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) :

> packrat::bundle()
The packrat project has been bundled at:
- "<leChemin>\PackratTest\packrat\bundles/PackratTest-2017-03-21.tar.gz"
# Oui le mélange "/" et "\" c'est Windows, c'est cadeau ...

Et ain­si votre col­lègue tout content n'aura plus qu'à récu­pé­rer la jolie archive, ins­tal­ler Packrat, et à uti­li­ser la fonc­tion com­plé­men­taire à cette pre­mière pour récu­pé­rer un envi­ron­ne­ment à l'identique, à l'exception que les packages R auront été com­pi­lés pour son OS.

Résul­tat du unbundle

Pour conclure

Packrat se révèle être très pra­tique et rapide pour vos pro­jets se ser­vant majo­ri­tai­re­ment des packages du CRAN ou d'un dépôt exté­rieur. Mais on pour­ra lui repro­cher le cas où c'est un package per­son­nel que vous sou­hai­tez joindre, il faut alors défi­nir un dépôt local. Une autre limi­ta­tion dans cette lignée sera le cas où les sources des packages sont absentes (oui oui même sur le ser­veur du CRAN), ce qui empê­che­ra de restaurer/​recompiler les sources pour un OS sans avoir  pas­ser par la case télé­char­ge­ment.

Pour ceux qui aiment uti­li­ser Rstu­dio, sachez qu'une ver­sion built-in existe pour vous don­ner un côté plus gra­phique à la ges­tion de votre envi­ron­ne­ment.

Enfin, si j'ai abor­dé ici la majo­ri­té des fonc­tion­na­li­tés de ce petit packages bien pra­tique, sachez qu'il reste quelques sub­ti­li­tés que je vous laisse décou­vrir par vous même en lisant la docu­men­ta­tion qui est claire et concise (donc pas d'excuse, 4 pages ça se lit vite, zou zou !)

 Références

[1]  https://​rstu​dio​.github​.io/​p​a​c​k​r​at/ [2]  https://​www​.you​tube​.com/​w​a​t​c​h​?​v​=​C​L​u​O​d​8​x​M​RRo

Mer­ci aux relec­teurs Yoann M., Mathu­rin et Zazo0o pour leur temps et leur œil à l’affût !

Vous avez aimé ? Dites-le nous !

Moyenne : 0 /​ 5. Nb de votes : 0

Pas encore de vote pour cet article.

We are sor­ry that this post was not use­ful for you !

Let us improve this post !

Tell us how we can improve this post ?




Commentaires

3 réponses à “Packrat ou comment gérer ses packages R par projet”

  1. Super article, mer­ci ! 🙂

    J'ai une petite ques­tion concer­nant les mises à jour de packages.
    Disons que je mette à jour un package, je test le code, et là catas­trophe, plus rien ne fonc­tionne à cause d'une rup­ture de rétro­com­pa­ti­bi­li­té ! La bonne atti­tude est de résoudre le pro­blème, mais disons que je sou­haite plu­tôt res­tau­rer l'ancienne ver­sion du package pour cause de poil dans la main ou dead line ser­rée. Packrat per­met-il de faire cela plus faci­le­ment ? Ou non ?

    1. Mer­ci 😀

      Je n'ai pas tes­té cela, mais si j'en crois la docu­men­ta­tion et si tu n'as pas acti­vé l'option auto.snapshot, il est pos­sible de récu­pé­rer ton ancien envi­ron­ne­ment en fai­sant un packrat::restore(). Cela va en fait de remettre ton envi­ron­ne­ment dans l'état "sau­ve­gar­dé".
      Si jamais cela ne fonc­tionne pas, une bonne idée serait de faire un bundle pré­ven­tif avant toute mise à jour. Et si jamais la mise à jour ne convient pas, sup­pri­mer l'environnement et de-bund­ler l'archive 🙂

Laisser un commentaire

Pour insérer du code dans vos commentaires, utilisez les balises <code> et <\code>.