- Le blog participatif de bioinformatique francophone depuis 2012 -

Packrat ou comment gérer ses packages R par projet

  • 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 :

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 :

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 :

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

 . 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.

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 :

 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.

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.

Use packrat::clean() to remove them. Or, if they are actual­ly nee­ded by your
pro­ject, add library(packagename) 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

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

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) :

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 !




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 🙂

  2. […] Gar­der les anciennes ver­sions peut même être utile pour faire tour­ner un script qui néces­si­te­rait un package qui lui n’est dis­po­nible que pour une ancienne ver­sion de R ! A moins d’utiliser le package packrat. […]

Laisser un commentaire