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