6  Comment choisir un package ?

6.1 Tâches concernées et recommandations

Vous souhaitez réaliser une tâche qui n’est pas décrite dans la documentation utilitR. Vous souhaitez donc déterminer si un package déjà existant répond à votre besoin et si vous pouvez l’utiliser.

Tâche concernée et recommandation

Choisir les packages qu’on utilise dans un programme est une tâche très importante et délicate. Il est normal d’y consacrer du temps. Pour rechercher un package adapté à une tâche, privilégier :

Vous pouvez utiliser un package dans un programme si les deux critères suivants sont remplis :

  • le package apporte réellement quelque chose à votre programme (rapidité d’exécution, simplicité et concision du code, simplification de tâches complexes…) ;
  • le package présente un niveau de risque suffisamment faible.

Le niveau de risque doit être d’autant plus faible que le package sera utilisé souvent et pendant une longue période. Il faut donc être plus exigeant pour les packages utilisés durablement en production que pour les packages utilisés pour une étude ponctuelle.

Vous pouvez évaluer le risque que présente l’utilisation d’un package grâce à l’analyse de différentes dimensions :

  • l’opportunité ;
  • la qualité de la documentation ;
  • la facilité d’utilisation ;
  • la popularité et la communauté d’utilisateurs ;
  • la réactivité de la maintenance ;
  • la qualité des développements ;
  • la réputation des auteurs.

6.2 Utiliser un package n’est pas un choix anodin

Utiliser des packages vous permet de gagner en productivité et de réaliser simplement des opérations complexes. Une des forces de l’écosystème R est le grand nombre de packages développés par des utilisateurs, qui enrichissent le langage de base et proposent des fonctions supplémentaires qui couvrent un éventail extrêmement large de tâches. En pratique, il est aujourd’hui inenvisageable (et inefficace) de mener un projet avec R sans faire appel à des packages. La preuve en est qu’une large part de la présente documentation porte sur les packages qui répondent aux besoins courants des statisticiens.

Toutefois, l’utilisation d’un package présente aussi des inconvénients. En effet, utiliser un package ajoute une dépendance au programme qu’on est en train d’écrire, ce qui est une source de fragilité. Les packages suivent un cycle de vie et peuvent se situer dans une phase où ils sont encore susceptibles d’évoluer : par exemple, une nouvelle version d’un package peut déprécier une fonction, ou en modifier le fonctionnement interne, et briser ainsi votre programme ; un package peut également être retiré du CRAN si son auteur ne souhaite plus le maintenir. Un code peut donc être fonctionnel au moment où on l’écrit, et ne plus fonctionner quelques mois plus tard si un des packages qu’il utilise a évolué 1.

Étant donné qu’un package peut lui-même dépendre d’autres packages, l’utilisation d’un seul package peut engendrer un nombre important de dépendances en cascade, et donc autant de sources de fragilité pour vos programmes. Pour trouver l’ensemble des dépendances d’un package, on peut utiliser la fonction tools::package_dependencies(). Voici comment trouver l’ensemble des dépendances du package rmarkdown :

tools::package_dependencies("rmarkdown", recursive = TRUE)
$rmarkdown
 [1] "bslib"       "evaluate"    "fontawesome" "htmltools"   "jquerylib"  
 [6] "jsonlite"    "knitr"       "methods"     "tinytex"     "tools"      
[11] "utils"       "xfun"        "yaml"        "base64enc"   "cachem"     
[16] "fastmap"     "grDevices"   "lifecycle"   "memoise"     "mime"       
[21] "rlang"       "sass"        "digest"      "highr"       "stats"      
[26] "cli"         "glue"        "fs"          "R6"          "rappdirs"   

Le point essentiel est donc le suivant : le simple fait qu’un package fasse (ou semble faire) ce que vous voulez n’est pas une raison suffisante de l’utiliser, surtout si votre programme doit rester fonctionnel pendant une longue période. Déterminer si on peut utiliser un package revient à faire un arbitrage entre avantages et inconvénients, et à évaluer le risque d’instabilité d’un package. De multiples facteurs permettent d’apprécier qualitativement ce risque.

Tip

Chaque nouvelle dépendance doit être ajoutée avec précaution. Il faut donc analyser chacune des dimensions présentées et déterminer si certains facteurs rendent le package inutilisable.

6.3 Comment trouver un package adapté à une tâche

Pour rechercher un package adapté à une tâche, privilégier :

Vous pouvez également rechercher des articles de blog ou poser la question sur des sites d’entraide (RStudio Community, par exemple).

Pour chaque package candidat, il est recommandé d’analyser le contenu du fichier DESCRIPTION qui comprend les méta-données du package. Ce fichier est disponible sur le site du CRAN à l’adresse https://cran.r-project.org/package=nomdupackage.

6.4 Comment savoir si vous pouvez utiliser un package

Déterminer si on peut utiliser un package revient à comparer les avantages et les risques que présente son utilisation. Les paragraphes qui suivent vous donnent des conseils simples pour mener cette analyse de risque.

6.4.1 L’opportunité

Utiliser un package comporte une part de risque. Cependant, ne pas utiliser de packages peut parfois être plus risqué. En effet, il serait inefficient voire dangereux de “réinventer la roue” s’il existe un package stable et éprouvé qui permet de réaliser une tâche complexe. Coder soi-même une tâche complexe peut conduire à un code difficilement maintenable, moins rapide, présentant des bugs et éventuellement des failles de sécurité. Le premier conseil est donc : vous pouvez utiliser un package à chaque fois que vous voulez réaliser une opération complexe à coder par vous-même.

On peut illustrer ces extrêmes au travers de deux exemples de tâches :

  • on veut tester si un vecteur numérique comprend des nombres impairs ; il serait inopportun d’utiliser la fonction is.odd() du package FSA alors qu’elle peut simplement s’écrire :

    is_odd <- function(x) {
      x %% 2 != 0
    }
  • on veut manipuler des données au format JSON ou XML ; il pourrait être tentant de se passer de package et d’employer des expressions régulières. Cependant, cette technique est reconnue comme dangereuse et dans ce cas, il est beaucoup plus prudent d’utiliser les packages jsonlite ou xml2, par exemple.

Tip

Il est envisageable d’utiliser un package s’il apporte réellement quelque chose à votre programme (rapidité d’exécution, simplicité et concision du code, simplification de tâches complexes…)

6.4.2 La qualité de la documentation

La présence d’une documentation riche, détaillée et présentant des exemples d’utilisation est un signe que le package a été développé avec soin. Les packages R offrent la possibilité de créer des pages de documentation appelées vignettes à cette fin. On peut lister les vignettes d’un package grâce à la fonction vignette().

Il est également devenu très simple pour les auteurs de packages de créer un site web compagnon de chacun de leur package. Lorsqu’il existe, ce site web est référencé dans la rubrique URL du fichier DESCRIPTION.

Tip

Ne pas utiliser de package ne comprenant ni vignette ni site web associé.

6.4.3 La facilité d’utilisation

Suivant le niveau de soin qui a été apporté à un package, l’utilisation peut être plus ou moins simple. Des packages mal conçus vont être complexes à utiliser :

  • nom des fonctions et des paramètres peu compréhensibles ;
  • besoin d’opérer de nombreuses étapes ou transformations de données afin d’utiliser les fonctions ;
  • messages d’erreurs peu explicites…
Tip

Ne pas utiliser de package qui apparaissent comme trop complexes.

6.4.4 Popularité et communauté d’utilisateurs

Utiliser un package confidentiel fait peser plusieurs risques potentiels :

  • difficulté à obtenir de l’aide ;
  • présence de bugs non détectés ;
  • adéquation du package à la tâche.

Il est difficile d’évaluer précisément la popularité d’un package. Il faut donc collecter des indices :

  • présence d’articles de blog par des rédacteurs autres que les auteurs du package (voir le site r-bloggers.com, par exemple) ;

  • présence de réponses à des questions sur ce package sur des sites d’entraide (stackoverflow.com, RStudio Community…) ;

  • nombre d’étoiles (stars) sur GitHub ou GitLab, les packages ayant moins de 30 étoiles pouvant être considérés comme confidentiels ;

  • nombre d’issues (ouvertes ou fermées) et de pull requests sur GitHub ou GitLab ;

  • le nombre de téléchargements du package ; étant donné que le CRAN dispose de nombreux miroirs, il est impossible de connaître le nombre total de téléchargements d’un package. Ceci dit, le package cranlogs permet d’obtenir le nombre de téléchargements depuis le miroir RStudio du CRAN (qui est très utilisé). Pour connaître le nombre de téléchargements du package ggplot2 le mois dernier :

    with(
      cranlogs::cran_downloads(packages = "ggplot2", when = "last-month"), 
      sum(count)
    )

    L’interprétation absolue de ces chiffres doit être effectuée avec prudence. En effet, il existe des robots qui effectuent des copies intégrales de l’ensemble des packages. Pour autant, on peut considérer qu’un nombre de téléchargements mensuels inférieur à 1 000 signale un package confidentiel.

Tip

Ne pas utiliser de package qui paraisse trop confidentiel.

6.4.5 Réactivité de la maintenance

Le risque principal est d’utiliser un package qui ne serait plus maintenu ou bien qui présenterait ce risque de façon accrue. Une façon relativement simple d’y parvenir est d’estimer le facteur d’autobus, défini comme le nombre minimal de contributeurs qu’il faut retirer à un projet pour le faire échouer ou s’arrêter. Plus précisément, il faut se méfier d’un package qui a un facteur d’autobus égal à 1, ce qui signifie que sa maintenance n’est assurée que par une seule personne.

Si le code source du package est hébergé sur GitHub (ce qui est le cas pour la majorité des packages), on peut facilement trouver le nombre de personnes ayant contribué à un package en allant dans l’onglet Insights et le volet Contributors. Par exemple, pour le package ggplot2, la liste des contributeurs se situe à cette adresse : https://github.com/tidyverse/ggplot2/graphs/contributors.

Il est important d’analyser ces contributions sur une période relativement récente (les deux dernières années, par exemple).

L’analyse de l’ensemble de l’activité sur GitHub ou GitLab est également un excellent moyen d’évaluer la réactivité de la maintenance : des issues et/ou des pull requests ouvertes et restées sans réponse depuis plusieurs mois sont le signe d’un projet peu réactif. Dans le doute, il est possible d’ouvrir une issue dans le projet afin de demander s’il est toujours activement maintenu (cette pratique est courante).

Tip

Ne pas utiliser de package qui présente de nombreuses issues restées sans réponse.

Se méfier très fortement des packages n’ayant qu’un seul contributeur.

6.4.6 Qualité des développements

Les auteurs de packages peuvent très facilement mettre en place des outils de qualimétrie permettant de repérer l’état dans lequel se situe le projet. En pratique, ces informations sont présentées au travers de badges colorés présents sur la page d’accueil du projet (sur GitHub ou GitLab).

On peut par exemple trouver :

  • le badge du cycle de vie ; au travers de ce badge, les auteurs signalent explicitement la phase dans laquelle se situe le projet.2. Il est recommandé de n’utiliser que des packages déclarés comme actifs ou stables.

    En cas d’absence de ce badge, on peut se référer au numéro de version du package ; en effet, il est d’usage que les versions considérées comme stables par leurs auteurs bénéficient d’un numéro de version majeur (le premier chiffre) strictement positif, tel que 1.0.0, 1.2.1, etc. Un package ayant un numéro de version majeur égal à 0 signale que le package n’est pas encore considéré comme stable par ses développeurs.

  • le taux de couverture de code par les tests ; ce badge s’appelle codecov ou coverage et la valeur qui est comprise indique le pourcentage de lignes de code faisant l’objet d’au moins un test. Il est recommandé de ne pas utiliser un package dont le taux de couverture par les tests est inférieur à 80 %. L’absence de ce badge est rédhibitoire car elle indique que les développeurs ne respectent pas les bonnes pratiques de développement.

  • l’utilisation de l’intégration continue ; ce badge s’appelle build, R-CMD-check ou encore pipeline. Il indique que les tests sont automatiquement effectués à chaque modification du code source du package. Il s’agit d’une bonne pratique que tout auteur de package se doit désormais d’employer. L’absence d’utilisation de l’intégration continue doit conduire à écarter le package.

En dehors des badges, on peut également utiliser le package goodpractice afin d’analyser la qualité du code d’un package.

Tip
  • Ne pas utiliser de package dont le code source n’est pas hébergé sur une forge telle que GitHub ou GitLab.
  • Ne pas utiliser de package qui n’utilise pas l’intégration continue.
  • Ne pas utiliser de package qui n’affiche pas le taux de couverture de code par les tests.

Une analyse plus approfondie du code source peut permettre de repérer l’utilisation d’autres bonnes pratiques telles que le linting.

6.4.7 Réputation des auteurs

Les auteurs de package ont des profils extrêmement divers : étudiants, statisticiens exerçant dans les secteurs publics ou privés, chercheurs, enseignants… des événements personnels ou professionnels peuvent les amener à maintenir moins activement un package voire à cesser toute activité dans le domaine. De façon générale, les packages développés par une organisation privée ou publique présentent un risque moindre d’être abandonnés.

De plus, développer des packages de qualité nécessite un peu d’expérience. Il est donc utile d’établir le profil des auteurs.

On peut facilement trouver les différents packages auxquels une personne a contribué en utilisant l’adresse suivante : https://www.rdocumentation.org/collaborators/name/Prenom%20Nom. Il est également possible de trouver la liste des packages dont la maintenance est assurée par une personne donnée, voir https://stackoverflow.com/a/10082179/.

Les packages de rOpenSci ou de RStudio sont toujours développés en appliquant des standards élevés, leur qualité est donc assurée, le seul risque résiduel étant celui lié à la maturité du projet qu’il faut vérifier.


  1. l’utilisation d’un gestionnaire de dépendances tel que [renv] (https://cran.r-project.org/package=renv) permet toutefois de figer la version des packages utilisés par un programme↩︎

  2. pour une description des différentes phases, voir https://www.repostatus.org/ ou https://www.tidyverse.org/lifecycle/↩︎