r devtools

35
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Construire un package R sans peine avec devtools, roxygen2 et testthat Jean-François Eudeline INSEE 1 er avril 2014

Upload: cornec

Post on 30-Jun-2015

1.268 views

Category:

Technology


3 download

DESCRIPTION

Presentation of R Devtools (in French) by Jean-Francois Eudeline

TRANSCRIPT

Page 1: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Construire un package R sans peineavec devtools, roxygen2 et testthat

Jean-François Eudeline

INSEE

1er avril 2014

Page 2: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Pourquoi créer des packages ?

• Beaucoup d’avantages :• fonctions réutilisables• facile à partager• code propre• maintenance facilitée• documentation standardisée

• mais :• plus long• coût d’apprentissage

L’utilisation du package devtools permet de minimiser les coûts de laconstruction d’un package en le rendant plus rapide et facile à apprendre.

Page 3: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Construction de package : les bases

devtools

roxygen2

testthat

Conclusion

Page 4: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Arborescence minimale

Monpackage

DESCRIPTIONNAMESPACER

fonctionsA.RfonctionsB.R

man

fonctionA1.RdfonctionA2.RdfonctionB1.RdfonctionB2.RdfonctionB3.Rd

Page 5: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Arborescence complèteMonpackage

DESCRIPTIONNAMESPACENEWSREADMERmantests

run-all.Rtestthat

datasrc

demoinst

CITATIONextdata

Page 6: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le fichier DESCRIPTIONPackage: RconjType: PackageTitle: Outils pour la prévision économique et la conception de sorties

automatiséesVersion: 0.1Date: 2014-01-15Author: Division des enquêtes de conjoncture (INSEE)Maintainer: Jean-François Eudeline <[email protected]>Description: Rconj est un package qui propose des outils pour définir et

calculer des modèles de prévision économique. Les modèles possiblessont les étalonnages et les équations à correction d'erreur. D'autrepart, il propose de nombreux outils destinés à exporter les résutats sousforme de tableaux et graphiques en code LaTeX ou HTML.

Depends:R (>= 2.10),zoo

Imports:dyn,xtable,tseries,urca,tikzDevice

License: GPL-3Encoding: UTF-8LazyData: true

Page 7: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le fichier NAMESPACE

export(vecm2step)import(dyn)import(tikzDevice)import(tseries)import(urca)import(xtable)import(zoo)

Page 8: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le dossier R/ et man/

• Le dossier R/ contient les codes des fonctions du package. Cesfonctions peuvent être regroupées en différents fichiers. On peutchoisir un fichier par fonction, un seul fichier au total, ou bien deregrouper les fonctions par thème.

• Le dossier man/ contient un fichier par fonction documentée. Cesfichiers en .Rd sont standardisés. Toutes les fonctions accessibles àl’utilisateur final doivent être documentées. Le package lui mêmepeut être documenté. Avec Roxygen2, on ne touche jamais à cesfichiers, ils sont générés automatiquement à partir des commentairesdans le code des fonctions.

Page 9: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Trois packages qui facilitent le développement

devtools fournit un jeu de fonctions qui rendent le développementde package aussi facile et rapide que possible.

roxygen2 traduit les commentaires du code source endocumentation R officielle.

testthat fournit un système simple pour les tests.

Page 10: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Pourquoi devtools ?

Devtools fournit des outils pour :• faciliter le processus de développement ;• faciliter la distribution du package ;• faciliter l’installation de packages qui ne sont pas sur le CRAN

Page 11: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Faciliter le processus de développement

Devtools fournit trois fonctions principales faciliter le chargement ducode, le tester et produire sa documentation :

• load_all(), charge le code R placé dans R/, compile et charge lecode C, C++ ou fortran placé dans src/, charge les données placéesdans data/, charge les dépendances et respecte les imports etexports du fichier NAMESPACE. load_all() simule unredémarrage de R puis le chargement du package.

• test() utilise le package testthat pour lancer les tests présent danstests/testthat. On peut ainsi effectuer les mêmes tests à chaquemodification du code.

• document() utilise le package roxygen2 pour convertir les blocs decommentaires en fichiers .Rd de documentation standard.

Page 12: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Faciliter la distribution et l’installation du package

• check() permet de lancer la commande R CMD check Pour déposerun package sur le CRAN, check() ne doit signaler aucune erreur niavertissement.

• build() convertit le dossier du package en un fichier unique. Sibinary=FALSE, il crée une archive tar.gz. Si binary=TRUE, il créeune archive .zip (sous windows). Cette archive est installable avec lafonction standard install.packages(). Un environnement dedéveloppement peut être nécessaire dans le premier cas.

• install() lance R CMD install pour installer le packagedirectement à partir des sources. install_github(),install_bitbucket(), install_gitorious(), andinstall_git() permettent d’installer un package à partir d’undépot internet.

Page 13: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Documenter avec roxygen2

• La méthode standard : on crée un fichier .Rd dans le dossier man/par objet (fonction, dataframe, classe, fonction générique ouméthode) à documenter. Ce fichier décrit l’objet , la documente, etdonne quelque exemples d’utilisation.

• Roxygen2 : on écrit la documentation au sein des fichiers de code,juste avant chaque fonction. Il suffit d’appeler la fonctiondocument() pour créer les fichiers .Rd.

Roxygen2 présente plusieurs avantages :• le code et la documentation sont ensemble, on peut modifier

simultanément la documentation et le code.• Inspection directe du code pour renseigner le .Rd.• Mise à jour automatique d’autres fichiers (NAMESPACE).• Unification de la synthaxe de documentation des différents objets

(méthodes S3 ou S4, méthodes génériques ou classes, données)

Page 14: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

La documentation au format roxygen I#' Équation à correction d'erreur#'#' vecm2step calcule un modèle à correction d'erreur en deux étapes selon la#' méthode de Stock et Watson (1993). Il est cependant possible d'effectuer une#' estimation en une étape (Stock 1987). L'estimation peut se faire avec#' variables instrumentales et/ou DOLS. Des tests de coïntégration sont#' effectués, le simulé en niveau est calculé ainsi que les contributions#' dynamiques#'#'#'#' @param formule_lt formule de long terme, sous la forme classique en R d'un#' objet formula. Les fonctions diff et lag sont bien gérées. Laisser à NULL#' (valeur par défaut) poru faire une estimation en une étape#' @param formule_ct formule de court terme. Dans le cas d'une estimation en#' deux étapes, les premières variables de l'expression de droite doivent être#' sous la forme lag(var1,-1) + ... + lag(varp,-1) où var1 est l'endogène de#' l'équation de long terme et var2, ..., varp sont, dans l'ordre, les#' explicatives.#' @param donnees jeu de données sur lequel est estimé le modèles. Doit être de#' classe mts.#' @param contrainte_lt contrainte sur l'équation de long terme. Doit être sous#' la forme d'un vecteur (une seule contrainte) ou d'une matrice (une ligne par#' contrainte). Un vecteur de contrainte est de la forme (a0, a1, ...,ak, b) où#' a0 + a1x1 + ... + akxk = b#' @param contrainte_ct contrainte sur l'équation de court terme en cas#' d'estimation en une seule étapes. Dans le cas d'une estimation en deux

Page 15: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

La documentation au format roxygen II#' étapes, la contrainte de court terme est calculée automatiquement, l'argument#' ne doit donc pas être renseigné.#' @param instrument vecteur de chaines de caractères contenant les noms des#' instruments utilisés.#' @param deb_estim date de début d'estimation. Par défaut, première date de#' disponibilité des données.#' @param fin_estim date de fin d'estimation. Par défaut, dernière date de#' disponibilité des données.#' @param deb_simule date de début de calcul du simulé.#' @param nb_lt nombre de variables dans l'équation de long terme. A renseigner#' en cas d'estimation en une seule étape.#' @param dols vecteur contenant les rangs des variables intervenant dans#' l'équation de long terme à reporter pour la force de rappel de l'équation#' de court terme#'#' @details Les dates de début et de fin d'estimation ainsi que celle du début#' de la simulation doivent être spécifiées comme pour les objets#' \code{\link{ts}}. Si toutes les données ne sont pas disponibles à ces dates,#' le programme la première (ou dernière) date pour laquelle toutes les données#' sont disponibles.#' @details Pour effectuer une estimation par DOLS, on ajoute, dans l'équation#' de long terme les lags passés et futurs et on précise, dans l'argument#' code{dols} les variables à conserver pour la force de rappel.#'#' @return retourne un objet de classe "vecm". Les fonction \code{print} et#' \code{summary} pour ce type d'objet n'est pas encore impémentée (TODO)#'

Page 16: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

La documentation au format roxygen III#' Un objet de classe "vecm" est une liste contenant les éléments suivants :#'#' \item{endogene}{nom de l'endogène de l'équation de court terme}#' \item{formule}{formule de court terme}#' \item{debut}{date de début d'estimation}#' \item{fin}{date de fin d'estimation}#' \item{coefficient}{table de résultat d'estimation}#' \item{var}{variance des résidus}#' \item{ssr}{somme des carrés des résidus}#' \item{residu}{series des résidus de l'équation}#' \item{r2bar}{R^2 ajusté}#' \item{contrib}{observé, simulé et contributions dynamiques des variables explicatives au niveau de l'endogène}#' \item{coefs_lt}{table de résultat de l'estimation de l'équation de long terme}#' \item{instrument}{instrument(s) éventuellement utilisé(s)}#' \item{test}{matrice à une colonne présentant dans tous les cas le R^2 ajusté,#' l'écart_type de l'endogène, le RMSE sur la période d'estimation et le#' RMSE après la période d'estimation.#' En cas d'estimation en deux étapes, elle donne également les pvalues des tests de Dickey-Fuller, de Phillips_Perron,#' et d'Eliott-Rothenberg-Stock. Notons que ces tests valident la stationnarité des résidus estimés de l'équation#' de long terme, et non des "vrais" résidus. En toute rigueur, ils ne sont donc pas utilisables si des#' coefficients sont estimés lors de la première étape.#' En cas d'estimation en une étape et si l'argument nb_lt est précisé,#' elle donne la t-stat du coefficient de force de rappel, le seuil du test, et le résultat du test.}#' \item{fit_vi}{En cas d'instrumentation, sortie du vecm de l'étape d'instrumentation}#'#'#' @keywords vecm ecm

Page 17: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

La documentation au format roxygen IV#' @export#' @encoding utf8#' @examples#' l.Inv_vol = log(donnees[,"td.p51s_d_7ch"])#' l.va_marchand_vol = log(donnees[,"va_marchand_vol"])#' l.ratio_prix = log(donnees[,"ratio_prix_fbcf_tot"])#' data_invt = cbind(l.Inv_vol,l.va_marchand_vol,l.ratio_prix)#' vecm_total = vecm2step(formule_lt=l.Inv_vol ~ l.va_marchand_vol + l.ratio_prix ,#' formule_ct=diff(l.Inv_vol) ~ lag(l.Inv_vol,-1) + lag(l.va_marchand_vol,-1) + lag(l.ratio_prix,-1) + diff(l.va_marchand_vol),#' donnees=data_invt,#' contrainte_lt=NULL,#' deb_estim=1989.75,#' fin_estim=2010.75)#' vecm_1step = vecm2step(formule_ct=diff(l.Inv_vol) ~ lag(l.Inv_vol,-1) + lag(l.va_marchand_vol,-1) + lag(l.ratio_prix,-1) + diff(l.va_marchand_vol),#' donnees=data_invt,#' contrainte_ct=rbind(c(0,1,1,0,0,0),c(0,1,0,-1,0,0)),#' deb_estim=1989.75,#' fin_estim=2010.75,#' nb_lt=3)vecm2step = function(formule_lt=NULL,formule_ct,donnees,contrainte_lt=NULL,contrainte_ct=NULL,

instrument=NULL,deb_estim=NULL,fin_estim=NULL,deb_simule=deb_estim,nb_lt=NULL,dols=NULL) { fit_vi=NULLnom_instrument=instrument

if(!is.null(instrument)) {

# Récupération de l'instrument...................

Page 18: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

La documentation au format roxygen V

..................}

Page 19: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le fichier .Rd I\encoding{utf8}\name{vecm2step}\alias{vecm2step}\title{Équation à correction d'erreur}\usage{vecm2step(formule_lt = NULL, formule_ct, donnees, contrainte_lt = NULL,

contrainte_ct = NULL, instrument = NULL, deb_estim = NULL,fin_estim = NULL, deb_simule = deb_estim, nb_lt = NULL, dols = NULL)

}\arguments{

\item{formule_lt}{formule de long terme, sous la formeclassique en R d'un objet formula. Les fonctions diff etlag sont bien gérées. Laisser à NULL (valeur pardéfaut) poru faire une estimation en une étape}

\item{formule_ct}{formule de court terme. Dans le casd'une estimation en deux étapes, les premièresvariables de l'expression de droite doivent être sous laforme lag(var1,-1) + ... + lag(varp,-1) où var1 estl'endogène de l'équation de long terme et var2, ...,varp sont, dans l'ordre, les explicatives.}

\item{donnees}{jeu de données sur lequel est estimé lemodèles. Doit être de classe mts.}

\item{contrainte_lt}{contrainte sur l'équation de longterme. Doit être sous la forme d'un vecteur (une seule

Page 20: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le fichier .Rd IIcontrainte) ou d'une matrice (une ligne par contrainte).Un vecteur de contrainte est de la forme (a0, a1, ...,ak,b) où a0 + a1x1 + ... + akxk = b}

\item{contrainte_ct}{contrainte sur l'équation de courtterme en cas d'estimation en une seule étapes. Dans lecas d'une estimation en deux étapes, la contrainte decourt terme est calculée automatiquement, l'argument nedoit donc pas être renseigné.}

\item{instrument}{vecteur de chaines de caractèrescontenant les noms des instruments utilisés.}

\item{deb_estim}{date de début d'estimation. Pardéfaut, première date de disponibilité des données.}

\item{fin_estim}{date de fin d'estimation. Par défaut,dernière date de disponibilité des données.}

\item{deb_simule}{date de début de calcul du simulé.}

\item{nb_lt}{nombre de variables dans l'équation de longterme. A renseigner en cas d'estimation en une seuleétape.}

\item{dols}{vecteur contenant les rangs des variablesintervenant dans l'équation de long terme à reporter

Page 21: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le fichier .Rd IIIpour la force de rappel de l'équation de court terme}

}\value{retourne un objet de classe "vecm". Les fonction\code{print} et \code{summary} pour ce type d'objet n'estpas encore impémentée (TODO)

Un objet de classe "vecm" est une liste contenant leséléments suivants :

\item{endogene}{nom de l'endogène de l'équation de courtterme} \item{formule}{formule de court terme}\item{debut}{date de début d'estimation} \item{fin}{datede fin d'estimation} \item{coefficient}{table de résultatd'estimation} \item{var}{variance des résidus}\item{ssr}{somme des carrés des résidus}\item{residu}{series des résidus de l'équation}\item{r2bar}{R^2 ajusté} \item{contrib}{observé, simuléet contributions dynamiques des variables explicatives auniveau de l'endogène} \item{coefs_lt}{table de résultatde l'estimation de l'équation de long terme}\item{instrument}{instrument(s) éventuellementutilisé(s)} \item{test}{matrice à une colonne présentantdans tous les cas le R^2 ajusté, l'écart_type del'endogène, le RMSE sur la période d'estimation et leRMSE après la période d'estimation. En cas d'estimationen deux étapes, elle donne également les pvalues des

Page 22: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le fichier .Rd IVtests de Dickey-Fuller, de Phillips_Perron, etd'Eliott-Rothenberg-Stock. Notons que ces tests valident lastationnarité des résidus estimés de l'équation de longterme, et non des "vrais" résidus. En toute rigueur, ilsne sont donc pas utilisables si des coefficients sontestimés lors de la première étape. En cas d'estimationen une étape et si l'argument nb_lt est précisé, elledonne la t-stat du coefficient de force de rappel, le seuildu test, et le résultat du test.} \item{fit_vi}{En casd'instrumentation, sortie du vecm de l'étaped'instrumentation}}\description{vecm2step calcule un modèle à correction d'erreur en deuxétapes selon la méthode de Stock et Watson (1993). Il estcependant possible d'effectuer une estimation en une étape(Stock 1987). L'estimation peut se faire avec variablesinstrumentales et/ou DOLS. Des tests de coïntégrationsont effectués, le simulé en niveau est calculé ainsique les contributions dynamiques}\details{Les dates de début et de fin d'estimation ainsi que celledu début de la simulation doivent être spécifiées commepour les objets \code{\link{ts}}. Si toutes les données nesont pas disponibles à ces dates, le programme lapremière (ou dernière) date pour laquelle toutes les

Page 23: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le fichier .Rd V

données sont disponibles.}\examples{l.Inv_vol = log(donnees[,"td.p51s_d_7ch"])l.va_marchand_vol = log(donnees[,"va_marchand_vol"])l.ratio_prix = log(donnees[,"ratio_prix_fbcf_tot"])data_invt = cbind(l.Inv_vol,l.va_marchand_vol,l.ratio_prix)vecm_total = vecm2step(formule_lt=l.Inv_vol ~ l.va_marchand_vol + l.ratio_prix ,

formule_ct=diff(l.Inv_vol) ~ lag(l.Inv_vol,-1) + lag(l.va_marchand_vol,-1) + lag(l.ratio_prix,-1) + diff(l.va_marchand_vol),donnees=data_invt,contrainte_lt=NULL,deb_estim=1989.75,fin_estim=2010.75)

vecm_1step = vecm2step(formule_ct=diff(l.Inv_vol) ~ lag(l.Inv_vol,-1) + lag(l.va_marchand_vol,-1) + lag(l.ratio_prix,-1) + diff(l.va_marchand_vol),donnees=data_invt,contrainte_ct=rbind(c(0,1,1,0,0,0),c(0,1,0,-1,0,0)),deb_estim=1989.75,fin_estim=2010.75,nb_lt=3)

}\keyword{ecm}\keyword{vecm}

Page 24: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

la documentation finale I

Page 25: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

la documentation finale II

Page 26: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

la documentation finale III

Page 27: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le structure des tests avec testthat

testthat permet d’effectuer des tests classés suivant une structurehiérarchique : expactation, test, context

• Une ”expectation” décrit le résultat que doit produire uneexpression : l’objet obtenu a-t-il la bonne valeur ou la bonne classe ?L’expression produit-elle le bon message d’erreur quand elle devrait ?Il y a 11 types d’”expectations”.

• Un ”test” regroupe plusieurs expectations pour tester une fonctiondonnée, ou des fonctionnalités proche d’une fonction donnée. Untest est créé par la fonction testthat().

• Un ”context” regroupe plusieurs tests relatifs à une fonctionnalitédonnée. Il est définit par la fonction context().

Les ”expectations” sont les outils pour traduire les test informels etiteractifs en scripts reproductibles. ”tests” et ”contexts” sont les moyensd’organiser l’ensemble des ”expectations” de manière à mieux situer lasource des problèmes éventuels.

Page 28: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

expectations

L’expectation retourne une valeur binaire suivant que la valeur retournéepar une expression est conforme ou non à ce que l’on attend. Si elleretourne FALSE, testthat indique une erreur.La syntaxe est assez simple, pour dire que l’on s’attend à ce que a soitégal à b, on écrit :

expect_that(a, equals(b))

Page 29: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Les 11 expectations I

• equals() utilise all.equal() pour vérifier l’égalité approchée.# Passes expect_that(10, equals(10))# Also passes expect_that(10, equals(10 + 1e-7))# Fails expect_that(10, equals(10 + 1e-6))# Definitely fails! expect_that(10, equals(11))

• is_identical_to() utilise identical() pour vérifier l’égalité exacte.# Passes expect_that(10, is_identical_to(10))# Fails expect_that(10, is_identical_to(10 + 1e-10))

• is_equivalent_to() est similaire à is_equals() mais ignore lesattributs de l’objet.# Fails expect_that(c("one" = 1, "two" = 2), equals(1:2))# Passes expect_that(c("one" = 1, "two" = 2), is_equivalent_to(1:2))

• is_a() vérifie que l’objet est une instance d’une certaine classe.model <- lm(mpg ~ wt, data = mtcars)# Passes expect_that(model, is_a("lm"))# Fails expect_that(model, is_a("glm"))

• matches() vérifie vérifie l’occurence d’un vecteur de caractères dansune expression.

Page 30: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Les 11 expectations IIstring <- "Testing is fun!"# Passes expect_that(string, matches("Testing"))# Fails, match is case-sensitive expect_that(string, matches("testing"))# Passes, match can be a regular expression expect_that(string, matches("t.+ting"))

• prints_text() vérifie l’occurence d’une chaine de caractères dans lasortie d’une expression.a <- list(1:10, letters)# Passes expect_that(str(a), prints_text("List of 2"))# Passes expect_that(str(a), prints_text(fixed("int [1:10]"))

• shows_message() vérifie si une expression conduit à un message.# Passes expect_that(library(mgcv), shows_message("This is mgcv"))

• gives_warning() vérifie si une expression conduit à un warning.# Passes expect_that(log(-1), gives_warning()) expect_that(log(-1), gives_warning("NaNs produced"))# Fails expect_that(log(0), gives_warning())

• throws_error() vérifie si une expression conduit à un erreur.# Fails expect_that(1 / 2, throws_error())# Passes expect_that(1 / "a", throws_error())# But better to be explicit expect_that(1 / "a", throws_error("non-numeric argument"))

• is_true() (is_false()) tests si une expression est vraie (ou fausse).Ces expectations permettent de traiter les cas non prévus par lesautres expectations.

Page 31: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Arborescence des tests

Les tests sont regroupés dans le dossier tests à la racine du package. Ledossier doit contenir :

• un fichier run-all.Rlibrary(testthat)library(MonPackage)test_check("MonPackage")

• Un dossier testthat contenant des fichiers test-xxx.R.

Page 32: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Exemple : test-str_length.R

context("String length")

test_that("str_length is number of characters", {expect_that(str_length("a"), equals(1))expect_that(str_length("ab"), equals(2))expect_that(str_length("abc"), equals(3))

})

test_that("str_length of missing is missing", {expect_that(str_length(NA), equals(NA_integer_))expect_that(str_length(c(NA, 1)), equals(c(NA, 1)))expect_that(str_length("NA"), equals(2))

})

test_that("str_length of factor is length of level", {expect_that(str_length(factor("a")), equals(1))expect_that(str_length(factor("ab")), equals(2))expect_that(str_length(factor("abc")), equals(3))

})

Page 33: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Un flux de travail possible

1. dans RStudio : file > New Project... > New Directory > R Package> Create project

2. on efface le fichier Read-and-delete-me3. on crée un fichier travail.R (cf. slide suivant) à la racine du package

et on ajoute la ligne travail.R au fichier .Rbuildignore4. On complète le fichier DESCRIPTION5. On écrit le code de la fonction et la documentation au format

roxygen6. On écrit les tests7. On vérifie la documentation et les tests dans le fichier travail.R

Les étapes 5 et 6 peuvent être inversée. Par exemple, pour corriger unbug, on peut reproduire le bug dans le fichier test puis on corrige lafonction jusqu’à ce que tous les tests passent.

Page 34: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Le fichier de travail

#chargement de devtoolslibrary(devtools)# génégation des fichiers de documentationdocument()# chargement du packageload_all()# vérification de la documentation de la fonctiondev_help("acquis_trim")# vérification des exemples liés à la fonctiondev_example("acquis_trim")# exécution des teststest()# vérification générale du packagecheck()# construction d'une archive "source" (.tar.gz)build()# construction d'une archive "binaire" (.zip sous windows, nécessite Rtools)build(binary=TRUE)# Les archives sont distribuables et installables avec install.packages()# On peut installer directement à partir du dossier source avec# la fonction install() de devtools

Page 35: R Devtools

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

...

.

Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion

Bibliographie

• Advance R Programing par Hadley WickhamLivre écrit par l’auteur des packages présentés ici. L’auteur présenteses outils dans la seconde partie du livre.

• Writing R Extensions documentation officielle du CRAN. C’est ladocumentation de référence. Un peu ardu comme première approchemais très utile pour résoudre les problèmes ensuite.