R: construire un package
Cette page reprend quelques idées de base pour faciliter la construction d'un package sous R.
Pour qui construire un package?
- Pour soi (réunir un certain nombre de fonctions, et les documenter pour un usage futur)
- Pour les autres (réunir un certain nombre de fonctions, les documenter et faciliter l'installation de ces fonctions par d'autres utilisateurs notamment via une installation plutôt que par des copier-collers de code.
Pourquoi construire un package?
- Pour réunir un certain nombre de fonctions s'intégrant dans une problématique commune
- Pour rendre son travail plus facilement reproductible que par un partage de script simple
- Pour partager et valoriser ses codes
Création de l'arborescence des fichiers
Dans le menu principal de RStudio, faire:
File => New Project => New Directory => R package
Le dossier est automatiquement construit et contient:
- ⚙️ .Rproj: le fichier indiquant à R les caractéristiques du projet. Le fait que le projet corresponde à un package fait apparaître un onglet "Build" en haut à droite de RStudio
- 📋 DESCRIPTION : le fichier de description du package (auteur, description de l'objectif du package, licence, etc.), à compléter / modifier
- 📋 NAMESPACE: le fichier (read-only) qui liste les fonctions du package, celles qui sont exportées (donc utilisables directement par les futurs utilisateurs du package) et les autres (celles qui servent au(x) développeur(s) uniquement)
- 📁 R: contient l'ensemble des scripts correspondant aux codes des fonctions
- 📁 man: (pour "manual") contient l'ensemble des fichiers d'aide i.e. la documentation associée à chaque fonction
Documentation des fonctions
La documentation des fonctions se fait via l'usage du package Roxygen.
Dans les options de projet sur RStudio (Tools => Project, faire
Build tools => cocher "Generate documentation with Roxygen"
ou bien
usethis::use_package_doc()
On peut par la suite dans l'éditeur se placer sur le corps d'une fonction, puis faire
🪄 => Insert Roxygen Skeleton (ou Ctrl + Alt + Shift + R)
Un squelette Roxygen est alors créé. Voici à quoi il ressemble (en supposant que votre fonction compte deux arguments arg1 et arg2
#' Title
#'
#' @param arg1
#' @param arg1
#' @return
#' @export
#' @examples
Et voici comment vous pouvez le compléter :
#' Estimates the value of the John Doe thingy
#'
#' @param arg1 number of this. Defaults to blah.
#' @param arg2 type of blah. You can choose among values "blah" or "blablah".
#' @return The estimates of blah
#' @export
#' @examples
blah <- mean(blahblah)
f(blah)
On peut alors faire
Build => More => Document (ou Ctrl + Shift + D)
Les fichiers d'aide (dans 📁 man) seront alors générés automatiquement
Correction formelle du package
On peut procéder à une vérification du package (R CMD check) en procédant comme suit:
Build => Check
Un certain nombre de vérifications sont exécutées, et vous obtiendrez en sortie un certain nombre d'erreurs, warnings ou notes qui vous orienteront sur des problèmes éventuels dans le code (et/ou la documentation) de vos fonctions.
Par exemple, un warning:
"Noms d'arguments dans le code mais pas dans la doc: arg3"
Cette vérification constitue une première évaluation du "niveau de qualité formelle" du package.
"Build" du package
Build => Install and Restart
permet de "construire" et charger le package. Cela permet notamment au développeur de tester les fonctions qu'il vient de développer "comme si" il était un utilisateur venant d'installer et charger le package dans son état actuel de développement
Partage du package
Dans un premier temps, on peut partager son package en version "dev", par exemple en lui faisant correspondre un repo github.
Pour cela: créez sur votre compte github un repo correspondant au nom du package (par exemple "blabla")
Indiquez à RStudio que vous allez utiliser git:
Tools => Project Options => Git/SVN => Version control system: Git
Les opérations classiques de Git (commit, push notamment) deviennent réalisables depuis un menu Git en haut à droite de RStudio
Indiquez en premier lieu l'origine distante du repo
par exemple https:://github.com/lvaudor/blabla
puis vous pouvez commencer à réaliser commits et pushs.
Votre package est installable par les utilisateurs via `devtools`:
devtools::install_github("lvaudor/blabla")
Indiquez-le dans un fichier README qui s'affichera en "page d'accueil" de votre repo github.
Dépendances
Le package utilise des fonctions provenant d'autres packages. Pour lister un package parmi les dépendances, on peut faire:
usethis::use_package("nom_package")
et le package sera ajouté à la liste des "Imports" dans le fichier 📋 DESCRIPTION
Cas spécial: dépendance à l'opérateur pipe %>%
usethis::use_pipe()
Tests
On peut mettre au point une batterie de "tests unitaires" pour s'assurer régulièrement du bon fonctionnement du package. Pour ce faire on peut utiliser le package testthat
usethis::use_testthat()
va créer
- 📁 tests/testthat et
- 📋 tests/testthat.R
Pour tester une fonction `f` en particulier:
usethis::use_test("f")
va créer 📋 tests/testthat/test-f.R qui contient un exemple de test unitaire
Dépôt du package
Quand le package est "assez mûr" il est possible de le déposer auprès du CRAN (qui va procéder à une batterie de vérifications formelles) ou d'autres instances type ROpenSci ("review" de package plus large: utilité, convivialité, etc.).