Programmer en R
Session de formation, décembre 2013
gilles.hunault "at" univ-angers.fr
Enoncés pour la séance numéro 4 (solutions)
Rappeler comment on utilise la fonction debug() pour tracer l'éxécution d'une fonction en R. En particulier, pourquoi ne faut-il pas nommer ses variables n, c ou Q ? On appliquera les commandes de débogage à la fonction sdu() suivante qui doit afficher les indices où on trouve des suites de k fois 1. Il n'y a pas d'erreur à l'exécution, mais les valeurs renvoyées sont incorrectes. Au passage, on pourra lire l'aide sur all(), any() et stopifnot().
Cet exemple a été repris de l'ouvrage de N. Matloff.
# attention, cette fonction est incorrecte pour # des raisons pédagogiques ; avec l'exemple en # fin, elle renvoie 3 4 5 7 au lieu de 4 5 8 sdu <- function(x,k) { n <- length(x) runs <- NULL for (i in 1:(n-k)) { if (all(x[i:i+k-1]==1)) { runs <- c(runs,i) } # fin si } # fin pour i return(runs) } # fin de fonction sdu print( sdu( c(1,0,0,1,1,1,0,1,1),2 ))Comment dépanner une fonction qui a une erreur à l'exécution ? En particulier, comment savoir où se situe l'erreur et à quel moment ? On appliquera les commandes R de dépannage à la fonction mind() suivante qui devrait afficher la distance minimale dans la matrice de distance et sa position dans la matrice.
# attention, cette fonction est incorrecte pour # des raisons pédagogiques ; avec l'exemple en # fin, elle provoque une erreur au lieu # de renvoyer 6 3 4 mind <- function( d ) { imin <- function(x) { # cette fonction est "locale" à mind lx <- length(x) i <- x[lx] j <- which.min(x[(i+1):(lx-1)]) k <- i+j return( c(k,x[k]) ) } # fin de fonction imin nb <- nrow(d) dd <- cbind(d,1:nb) # rappel du numéro de ligne wmins <- apply(dd[-nb,],1,imin) i <- which.min(wmins[1,]) j <- wmins[2,i] return( c(d[i,j],i,j) ) } # fin de fonction mind matq <- matrix(nrow=5,ncol=5) matq[1,] <- c( 0,12,13, 8,20) matq[2,] <- c(12, 0,15,28,88) matq[3,] <- c(13,15, 0, 6, 9) matq[4,] <- c( 8,28, 6, 0,33) matq[5,] <- c(20,88, 9,33, 0) dm <- mind( matq ) cat(" distance min :",dm[1]," vue en col lig ",dm[-1],"\n")Cet exemple a aussi été repris de l'ouvrage de N. Matloff.
Notre fonction duree() permet de savoir combien de temps dure l'exécution d'une instruction, mais elle ne détaille rien. Quelles fonctions sont fournies par R pour le profilage ? On pourra les tester avec les 4 implémentations de puissance d'un vecteur suivantes :
powers1 <- function(x,dg) { pw <- matrix(x,nrow=length(x)) prod <- x for (i in 2:dg) { prod <- prod * x pw <- cbind(pw,prod) } # fin pour i return(pw) } # fin de fonction powers1 powers2 <- function(x,dg) { pw <- matrix(x,nrow=length(x),ncol=dg) prod <- x pw[,1] <- prod for (i in 2:dg) { prod <- prod * x pw[,i] <- prod } # fin pour i return(pw) } # fin de fonction powers2 powers3 <- function(x,dg) { return( outer(x,1:dg,"^") ) } # fin de fonction powers3 powers4 <- function(x,dg) { repx <- matrix(rep(x,dg),nrow=length(x)) return( t(apply(repx,1,cumprod)) ) } # fin de fonction powers4 # test des fonctions v <- 1:5 w1 <- powers1(v,5) w2 <- powers2(v,5) w3 <- powers3(v,5) w4 <- powers4(v,5) cats("powers1") print(w1) cats("powers2") print(w2) cats("les 4 méthodes") print( cbind(w1,w2,w3,w4) ) cats("comparaison des durées des 4 méthodes") v <- runif(5000) nbe <- 500 cat("powers1 ") duree( t1 <- system.time(powers1(v,nbe)) ) cat("powers2 ") duree( t2 <- system.time(powers2(v,nbe)) ) cat("powers3 ") duree( t3 <- system.time(powers3(v,nbe)) ) cat("powers4 ") duree( t4 <- system.time(powers4(v,nbe)) ) print( rbind(t1,t2,t3,t4) )Y a-t-il une meilleure façon de nommer ses variables, ses fonctions ? Que faut-il documenter et commenter quand on programme pour soi ? et pour les autres ? Faut-il indenter les structures ?
Quelles aides faut-il fournir à l'utilisateur ? Faut-il fournir des jeux d'essais ou des vecteurs de données d'exemples ?
Comment est implémentée la notion d'objet en R ? Comment écrire ses propres objets en R ?
Qu'est-ce que les classes S3 et S4 ?
Essayer d'implémenter une classe S4 d'objets nommée VS (variable statistique) avec deux sous-classes : les VQT (variables statistiques quantitatives) et les VQL (variables statistiques qualitatives).
Est-ce difficile d'écrire un package en R ? Quelles sont les étapes de création d'un package ?
Y a-t-il une autre façon de distribuer ou de faire partager ses fonctions ?
Quels sont les objets usuels renvoyés par les tests, les régressions ? Quelles sont les fonctions associées ?
Je voudrais comprendre, dans une analyse discriminante linéaire via lda() du package MASS comment sont calculées les probabilités dites a posteriori pour chaque groupe au niveau des observations. Quelle fonction est utilisée ? Quel est son code-source ?
Comment progresser en programmation R à la suite de ces cours ?
Retour à la page principale de (gH)