Uploaded on

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

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

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
728
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
7
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 1er avril 2014
  • 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 la construction d’un package en le rendant plus rapide et facile à apprendre.
  • 3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Construction de package : les bases devtools roxygen2 testthat Conclusion
  • 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Arborescence minimale Monpackage DESCRIPTION NAMESPACE R fonctionsA.R fonctionsB.R man fonctionA1.Rd fonctionA2.Rd fonctionB1.Rd fonctionB2.Rd fonctionB3.Rd
  • 5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Arborescence complète Monpackage DESCRIPTION NAMESPACE NEWS README R man tests run-all.R testthat data src demo inst CITATION extdata
  • 6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Le fichier DESCRIPTION Package: Rconj Type: Package Title: Outils pour la prévision économique et la conception de sorties automatisées Version: 0.1 Date: 2014-01-15 Author: Division des enquêtes de conjoncture (INSEE) Maintainer: Jean-François Eudeline <jean-francois.eudeline@insee.fr> Description: Rconj est un package qui propose des outils pour définir et calculer des modèles de prévision économique. Les modèles possibles sont les étalonnages et les équations à correction d'erreur. D'autre part, il propose de nombreux outils destinés à exporter les résutats sous forme de tableaux et graphiques en code LaTeX ou HTML. Depends: R (>= 2.10), zoo Imports: dyn, xtable, tseries, urca, tikzDevice License: GPL-3 Encoding: UTF-8 LazyData: true
  • 7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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)
  • 8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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. Ces fonctions peuvent être regroupées en différents fichiers. On peut choisir un fichier par fonction, un seul fichier au total, ou bien de regrouper les fonctions par thème. • Le dossier man/ contient un fichier par fonction documentée. Ces fichiers en .Rd sont standardisés. Toutes les fonctions accessibles à l’utilisateur final doivent être documentées. Le package lui même peut être documenté. Avec Roxygen2, on ne touche jamais à ces fichiers, ils sont générés automatiquement à partir des commentaires dans le code des fonctions.
  • 9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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éveloppement de package aussi facile et rapide que possible. roxygen2 traduit les commentaires du code source en documentation R officielle. testthat fournit un système simple pour les tests.
  • 10. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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
  • 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Faciliter le processus de développement Devtools fournit trois fonctions principales faciliter le chargement du code, le tester et produire sa documentation : • load_all(), charge le code R placé dans R/, compile et charge le code C, C++ ou fortran placé dans src/, charge les données placées dans data/, charge les dépendances et respecte les imports et exports du fichier NAMESPACE. load_all() simule un redémarrage de R puis le chargement du package. • test() utilise le package testthat pour lancer les tests présent dans tests/testthat. On peut ainsi effectuer les mêmes tests à chaque modification du code. • document() utilise le package roxygen2 pour convertir les blocs de commentaires en fichiers .Rd de documentation standard.
  • 12. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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époser un package sur le CRAN, check() ne doit signaler aucune erreur ni avertissement. • build() convertit le dossier du package en un fichier unique. Si binary=FALSE, il crée une archive tar.gz. Si binary=TRUE, il crée une archive .zip (sous windows). Cette archive est installable avec la fonction standard install.packages(). Un environnement de développement peut être nécessaire dans le premier cas. • install() lance R CMD install pour installer le package directement à partir des sources. install_github(), install_bitbucket(), install_gitorious(), and install_git() permettent d’installer un package à partir d’un dépot internet.
  • 13. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 ou méthode) à documenter. Ce fichier décrit l’objet , la documente, et donne quelque exemples d’utilisation. • Roxygen2 : on écrit la documentation au sein des fichiers de code, juste avant chaque fonction. Il suffit d’appeler la fonction document() 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)
  • 14. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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
  • 15. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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) #'
  • 16. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 #' 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 #' et d'Eliott-Rothenberg-Stock. Notons que ces tests valident la stationnarité des résidus #' de long terme, et non des "vrais" résidus. En toute rigueur, ils ne sont donc pas utilis #' 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 #' item{fit_vi}{En cas d'instrumentation, sortie du vecm de l'étape d'instrumentation} #' #' #' @keywords vecm ecm
  • 17. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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) + l #' 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_marchan #' 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=NU instrument=NULL,deb_estim=NULL,fin_estim=NULL,deb_simule=deb_estim,nb_ nom_instrument=instrument if(!is.null(instrument)) { # Récupération de l'instrument ...................
  • 18. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion La documentation au format roxygen V .................. }
  • 19. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 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} item{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.} item{donnees}{jeu de données sur lequel est estimé le modèles. Doit être de classe mts.} item{contrainte_lt}{contrainte sur l'équation de long terme. Doit être sous la forme d'un vecteur (une seule
  • 20. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Le fichier .Rd II 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} item{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 étapes, la contrainte de court terme est calculée automatiquement, l'argument ne doit donc pas être renseigné.} item{instrument}{vecteur de chaines de caractères contenant les noms des instruments utilisés.} item{deb_estim}{date de début d'estimation. Par dé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 long terme. A renseigner en cas d'estimation en une seule étape.} item{dols}{vecteur contenant les rangs des variables intervenant dans l'équation de long terme à reporter
  • 21. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Le fichier .Rd III pour 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'est pas 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 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
  • 22. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Le fichier .Rd IV 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} } description{ 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 } 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
  • 23. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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( 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_v 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}
  • 24. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion la documentation finale I
  • 25. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion la documentation finale II
  • 26. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion la documentation finale III
  • 27. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 structure hiérarchique : expactation, test, context • Une ”expectation” décrit le résultat que doit produire une expression : 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 fonction donnée, ou des fonctionnalités proche d’une fonction donnée. Un test 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 et iteractifs en scripts reproductibles. ”tests” et ”contexts” sont les moyens d’organiser l’ensemble des ”expectations” de manière à mieux situer la source des problèmes éventuels.
  • 28. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion expectations L’expectation retourne une valeur binaire suivant que la valeur retournée par une expression est conforme ou non à ce que l’on attend. Si elle retourne 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))
  • 29. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 les attributs 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 dans une expression.
  • 30. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Les 11 expectations II string <- "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 la sortie 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("Na # 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 les autres expectations.
  • 31. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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. Le dossier doit contenir : • un fichier run-all.R library(testthat) library(MonPackage) test_check("MonPackage") • Un dossier testthat contenant des fichiers test-xxx.R.
  • 32. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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)) })
  • 33. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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-me 3. on crée un fichier travail.R (cf. slide suivant) à la racine du package et on ajoute la ligne travail.R au fichier .Rbuildignore 4. On complète le fichier DESCRIPTION 5. On écrit le code de la fonction et la documentation au format roxygen 6. On écrit les tests 7. 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 un bug, on peut reproduire le bug dans le fichier test puis on corrige la fonction jusqu’à ce que tous les tests passent.
  • 34. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Le fichier de travail #chargement de devtools library(devtools) # génégation des fichiers de documentation document() # chargement du package load_all() # vérification de la documentation de la fonction dev_help("acquis_trim") # vérification des exemples liés à la fonction dev_example("acquis_trim") # exécution des tests test() # vérification générale du package check() # 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
  • 35. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction Construction de package : les bases devtools roxygen2 testthat Conclusion Bibliographie • Advance R Programing par Hadley Wickham Livre écrit par l’auteur des packages présentés ici. L’auteur présente ses outils dans la seconde partie du livre. • Writing R Extensions documentation officielle du CRAN. C’est la documentation de référence. Un peu ardu comme première approche mais très utile pour résoudre les problèmes ensuite.