Incorporation de code C en R
   Création d’un package en R




Incorporation de code C en R
  Création d’un package R

                    Pierre Alquier




Groupe de travail R, mercredi 2 mai 2012


               Pierre Alquier   C/R/Packages
Incorporation de code C en R
               Création d’un package en R


Plan




 1   Incorporation de code C en R


 2   Création d’un package en R




                           Pierre Alquier   C/R/Packages
Incorporation de code C en R
                Création d’un package en R


Pourquoi utiliser du code C en R ?

  L’execution de programmes écrits en R est souvent assez lente,
  en particulier en présence de boucles.
  Un exemple idiot :

   f = function(X)
   {
      RES = 0
      for (i in 1:length(X)) RES = RES + X[i]
      return(RES)
   }



                            Pierre Alquier   C/R/Packages
Incorporation de code C en R
                  Création d’un package en R


La solution !


  Lorsqu’on peut, il faut éviter les boucles et utiliser les
  fonctions R. Dans l’exemple :

   sum(X)

  fait l’affaire...




                              Pierre Alquier   C/R/Packages
Incorporation de code C en R
                  Création d’un package en R


La solution !


  Lorsqu’on peut, il faut éviter les boucles et utiliser les
  fonctions R. Dans l’exemple :

   sum(X)

  fait l’affaire...

  Si ça n’est pas possible, une autre solution consiste à écrire la
  fonction en C, donc l’exécution est beaucoup plus rapide.




                              Pierre Alquier   C/R/Packages
Incorporation de code C en R
                 Création d’un package en R


Ecriture de la fonction en C
  Dans le fichier :
   nomfichier.c
  on écrit :
   #include <R.h>
   #include <Rmath.h>

   void somme(double *x, double *res, int *lg)
   {
      int i;

       for (i=0;i<*lg;i++) *res += x[i];
   }
                             Pierre Alquier   C/R/Packages
Incorporation de code C en R
               Création d’un package en R


Compilation du code C

 La première étape consiste à compiler le code C à l’aide du
 compilateur C. Dans l’invite de commande shell (linux) ou
 DOS (windows) :

 R CMD SHLIB nomfichier.c

 Ceci va créer un objet dynamique (.so) sous linux ou une
 librairie dynamique (.dll) sous windows.
 Ensuite, il faut, sous R, appeler cette librairie :

 dyn.load("nomfichier.so")

 (ou .dll si on travaille sous windows).


                           Pierre Alquier   C/R/Packages
Incorporation de code C en R
                Création d’un package en R


La fonction .C() de R


  Appel du code C en R via la fonction .C() de R. Attention,
  cette fonction prend en argument :
    1  le nom de la fonction C ;
    2  les variables que l’on donne à manger à cette fonction.
  Cette fonction donne en sortie une liste qui contient comme
  champs :
    1  les variables que l’on a donné à manger à la fonction et
       qui ont pu être modifiées entre temps.




                            Pierre Alquier   C/R/Packages
Incorporation de code C en R
               Création d’un package en R


La fonction .C() de R


  Appel du code C en R :

  g = function(X)
  {
     LG = length(X)
     A = .C("somme",x=as.double(X),res=as.double(0),
                                   lg=as.integer(LG))
     return(A$res)
  }




                           Pierre Alquier   C/R/Packages
Incorporation de code C en R
                Création d’un package en R


Création d’un package en R




  1   Incorporation de code C en R


  2   Création d’un package en R




                            Pierre Alquier   C/R/Packages
Incorporation de code C en R
                  Création d’un package en R


Pourquoi créer un package ?


  Pourquoi créer un package plutôt que de diffuser directement
  son code en R et en C ?
    1   essentiellement, en travaillant un peu plus, on évite à
        l’utilisateur de devoir gérer les appels à la fonction .C(),
        compiler lui-même, etc...
    2   on obtient un joli produit fini que l’on peut mettre à
        disposition des utilisateurs sur sa page web ou même le
        soumettre sur le site de R.




                              Pierre Alquier   C/R/Packages
Incorporation de code C en R
                 Création d’un package en R


La fonction package.skeleton()

  On souhaite créer le package “MCornec” qui contient deux
  fonctions, “f1” et “f2”, chacune écrite en R mais pouvant
  appeler du code C par l’intermédiaire de la fonction .C(), ainsi
  qu’un jeu de données “data1”.
    1   écrire tous les codes en R et en C et charger toutes les
        fonctions et jeux de données en mémoire ; ie “f1”, “f2” et
        “data1”.
    2   appeler sous R la fonction :
         package.skeleton(list=c("f1","f2","data1"),
                                                  name="MCornec")


                             Pierre Alquier   C/R/Packages
Incorporation de code C en R
                Création d’un package en R


La structure du package

  Ceci aura eu pour effet de créer dans le répertoire courant la
  structure du package :

   ./MCornec/data/data1.rda
   ./MCornec/man/data1.Rd
   ./MCornec/man/f1.Rd
   ./MCornec/man/f2.Rd
   ./MCornec/man/MCornec-package.Rd
   ./MCornec/R/f1.R
   ./MCornec/R/f2.R
   ./MCornec/Read-and-delete-me
   ./MCornec/DESCRIPTION


                            Pierre Alquier   C/R/Packages
Incorporation de code C en R
               Création d’un package en R


La documentation

 Les fichiers :

  ./MCornec/man/data1.Rd
  ./MCornec/man/f1.Rd
  ./MCornec/man/f2.Rd
  ./MCornec/man/MCornec-package.Rd
  ./MCornec/DESCRIPTION

 sont des formulaires dont il faut remplir les champs : que fait
 la fonction, quels sont ses arguments, qui l’a écrite, etc...
 Attention, si il est mal rempli, ceci causera des messages
 d’erreurs lors de la compilation du package.


                           Pierre Alquier   C/R/Packages
Incorporation de code C en R
               Création d’un package en R


Le code C
 Si du code C est appelé par une des fonctions R, celui-ci doit
 être ajouté dans le package. Il faut créer le répertoire :

  ./MCornec/src/

 et mettre dedans un unique fichier .c contenant le code. Il faut
 également créer le fichier suivant :

  ./MCornec/R/zzz.R

 contenant uniquement le code

  .First.lib = function(lib,pkg) {
     library.dynam("MCornec",pkg,lib)
  }

                           Pierre Alquier   C/R/Packages
Incorporation de code C en R
                Création d’un package en R


La compilation : sous linux

  Dans le répertoire courant, dans le shell :

   R CMD check MCornec

  vérifie que le package est en état d’être compilé, puis :

   R CMD build MCornec

  crée le package dans le fichier

   ./MCornec.tar.gz

  prêt à être installé sous R sur n’importe quel ordinateur.


                            Pierre Alquier   C/R/Packages
Incorporation de code C en R
                Création d’un package en R


La compilation : sous windows

  Dans le répertoire courant, dans l’invite de commande
  MS-DOS :

   R CMD check MCornec
   R CMD build --binary MCornec

  compile et crée le package dans le fichier

   ./MCornec.zip

  Attention, pour que ceci fonctionne, il faudra avoir
  préalablement installé (en plus de R) un compilateur LaTeX,
  un compilateur C, les outils Perl, Rtools (disponibles sur
  internet) et s’assurer que tous ces outils sont dans le PATH.

                            Pierre Alquier   C/R/Packages
Incorporation de code C en R
                     Création d’un package en R


Sources / pour aller plus loin

  Ces slides ont été essentiellement préparés à partir du
  document :
      Sophie Baillargeon (Université Laval). Programmation en R : incorporation de code C et création
      de packages, 2007.
      Disponible en ligne, par exemple :
      http ://www.mat.ulaval.ca/fileadmin/informatique/LogicielR/ProgR_AppelC_Package.pdf



  Egalement, on trouve une documentation très très complète
  sur le site de R mais qui s’adresse déjà à des codeurs
  expérimentés :

      R Development Core Team. Writing R Extensions, 2012 (pour la version 2.15.0 de R).
      Disponible en ligne :
      http ://cran.r-project.org/doc/manuals/R-exts.pdf




                                  Pierre Alquier     C/R/Packages

Incorporer du C dans R, créer son package

  • 1.
    Incorporation de codeC en R Création d’un package en R Incorporation de code C en R Création d’un package R Pierre Alquier Groupe de travail R, mercredi 2 mai 2012 Pierre Alquier C/R/Packages
  • 2.
    Incorporation de codeC en R Création d’un package en R Plan 1 Incorporation de code C en R 2 Création d’un package en R Pierre Alquier C/R/Packages
  • 3.
    Incorporation de codeC en R Création d’un package en R Pourquoi utiliser du code C en R ? L’execution de programmes écrits en R est souvent assez lente, en particulier en présence de boucles. Un exemple idiot : f = function(X) { RES = 0 for (i in 1:length(X)) RES = RES + X[i] return(RES) } Pierre Alquier C/R/Packages
  • 4.
    Incorporation de codeC en R Création d’un package en R La solution ! Lorsqu’on peut, il faut éviter les boucles et utiliser les fonctions R. Dans l’exemple : sum(X) fait l’affaire... Pierre Alquier C/R/Packages
  • 5.
    Incorporation de codeC en R Création d’un package en R La solution ! Lorsqu’on peut, il faut éviter les boucles et utiliser les fonctions R. Dans l’exemple : sum(X) fait l’affaire... Si ça n’est pas possible, une autre solution consiste à écrire la fonction en C, donc l’exécution est beaucoup plus rapide. Pierre Alquier C/R/Packages
  • 6.
    Incorporation de codeC en R Création d’un package en R Ecriture de la fonction en C Dans le fichier : nomfichier.c on écrit : #include <R.h> #include <Rmath.h> void somme(double *x, double *res, int *lg) { int i; for (i=0;i<*lg;i++) *res += x[i]; } Pierre Alquier C/R/Packages
  • 7.
    Incorporation de codeC en R Création d’un package en R Compilation du code C La première étape consiste à compiler le code C à l’aide du compilateur C. Dans l’invite de commande shell (linux) ou DOS (windows) : R CMD SHLIB nomfichier.c Ceci va créer un objet dynamique (.so) sous linux ou une librairie dynamique (.dll) sous windows. Ensuite, il faut, sous R, appeler cette librairie : dyn.load("nomfichier.so") (ou .dll si on travaille sous windows). Pierre Alquier C/R/Packages
  • 8.
    Incorporation de codeC en R Création d’un package en R La fonction .C() de R Appel du code C en R via la fonction .C() de R. Attention, cette fonction prend en argument : 1 le nom de la fonction C ; 2 les variables que l’on donne à manger à cette fonction. Cette fonction donne en sortie une liste qui contient comme champs : 1 les variables que l’on a donné à manger à la fonction et qui ont pu être modifiées entre temps. Pierre Alquier C/R/Packages
  • 9.
    Incorporation de codeC en R Création d’un package en R La fonction .C() de R Appel du code C en R : g = function(X) { LG = length(X) A = .C("somme",x=as.double(X),res=as.double(0), lg=as.integer(LG)) return(A$res) } Pierre Alquier C/R/Packages
  • 10.
    Incorporation de codeC en R Création d’un package en R Création d’un package en R 1 Incorporation de code C en R 2 Création d’un package en R Pierre Alquier C/R/Packages
  • 11.
    Incorporation de codeC en R Création d’un package en R Pourquoi créer un package ? Pourquoi créer un package plutôt que de diffuser directement son code en R et en C ? 1 essentiellement, en travaillant un peu plus, on évite à l’utilisateur de devoir gérer les appels à la fonction .C(), compiler lui-même, etc... 2 on obtient un joli produit fini que l’on peut mettre à disposition des utilisateurs sur sa page web ou même le soumettre sur le site de R. Pierre Alquier C/R/Packages
  • 12.
    Incorporation de codeC en R Création d’un package en R La fonction package.skeleton() On souhaite créer le package “MCornec” qui contient deux fonctions, “f1” et “f2”, chacune écrite en R mais pouvant appeler du code C par l’intermédiaire de la fonction .C(), ainsi qu’un jeu de données “data1”. 1 écrire tous les codes en R et en C et charger toutes les fonctions et jeux de données en mémoire ; ie “f1”, “f2” et “data1”. 2 appeler sous R la fonction : package.skeleton(list=c("f1","f2","data1"), name="MCornec") Pierre Alquier C/R/Packages
  • 13.
    Incorporation de codeC en R Création d’un package en R La structure du package Ceci aura eu pour effet de créer dans le répertoire courant la structure du package : ./MCornec/data/data1.rda ./MCornec/man/data1.Rd ./MCornec/man/f1.Rd ./MCornec/man/f2.Rd ./MCornec/man/MCornec-package.Rd ./MCornec/R/f1.R ./MCornec/R/f2.R ./MCornec/Read-and-delete-me ./MCornec/DESCRIPTION Pierre Alquier C/R/Packages
  • 14.
    Incorporation de codeC en R Création d’un package en R La documentation Les fichiers : ./MCornec/man/data1.Rd ./MCornec/man/f1.Rd ./MCornec/man/f2.Rd ./MCornec/man/MCornec-package.Rd ./MCornec/DESCRIPTION sont des formulaires dont il faut remplir les champs : que fait la fonction, quels sont ses arguments, qui l’a écrite, etc... Attention, si il est mal rempli, ceci causera des messages d’erreurs lors de la compilation du package. Pierre Alquier C/R/Packages
  • 15.
    Incorporation de codeC en R Création d’un package en R Le code C Si du code C est appelé par une des fonctions R, celui-ci doit être ajouté dans le package. Il faut créer le répertoire : ./MCornec/src/ et mettre dedans un unique fichier .c contenant le code. Il faut également créer le fichier suivant : ./MCornec/R/zzz.R contenant uniquement le code .First.lib = function(lib,pkg) { library.dynam("MCornec",pkg,lib) } Pierre Alquier C/R/Packages
  • 16.
    Incorporation de codeC en R Création d’un package en R La compilation : sous linux Dans le répertoire courant, dans le shell : R CMD check MCornec vérifie que le package est en état d’être compilé, puis : R CMD build MCornec crée le package dans le fichier ./MCornec.tar.gz prêt à être installé sous R sur n’importe quel ordinateur. Pierre Alquier C/R/Packages
  • 17.
    Incorporation de codeC en R Création d’un package en R La compilation : sous windows Dans le répertoire courant, dans l’invite de commande MS-DOS : R CMD check MCornec R CMD build --binary MCornec compile et crée le package dans le fichier ./MCornec.zip Attention, pour que ceci fonctionne, il faudra avoir préalablement installé (en plus de R) un compilateur LaTeX, un compilateur C, les outils Perl, Rtools (disponibles sur internet) et s’assurer que tous ces outils sont dans le PATH. Pierre Alquier C/R/Packages
  • 18.
    Incorporation de codeC en R Création d’un package en R Sources / pour aller plus loin Ces slides ont été essentiellement préparés à partir du document : Sophie Baillargeon (Université Laval). Programmation en R : incorporation de code C et création de packages, 2007. Disponible en ligne, par exemple : http ://www.mat.ulaval.ca/fileadmin/informatique/LogicielR/ProgR_AppelC_Package.pdf Egalement, on trouve une documentation très très complète sur le site de R mais qui s’adresse déjà à des codeurs expérimentés : R Development Core Team. Writing R Extensions, 2012 (pour la version 2.15.0 de R). Disponible en ligne : http ://cran.r-project.org/doc/manuals/R-exts.pdf Pierre Alquier C/R/Packages