viernes, 11 de febrero de 2011

R Learning - Building R packages that integrates C++ via Rcpp - n.4 (linking with LGL)

So, as I stated before, it is time to see if I can integrate C++ code that uses the Lemon Graph Library into R via Rcpp (see these sequel of previous posts: here, here, here and here).

In my first approach I will not use modules (a tool provided by Rcpp). So I start a new pakage skeleton from a R console:

> require("Rcpp")
Loading required package: Rcpp
> Rcpp.package.skeleton("pkgwithlgl")
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Further steps are described in './pkgwithlgl/Read-and-delete-me'.

Adding Rcpp settings
 >> added Depends: Rcpp
 >> added LinkingTo: Rcpp
 >> added useDynLib directive to NAMESPACE
 >> added Makevars file with Rcpp settings
 >> added file with Rcpp settings
 >> added example header file using Rcpp classes
 >> added example src file using Rcpp classes
 >> added example R file calling the C++ example
 >> added Rd file for rcpp_hello_world

Now inside the directory where I run the R console I found a directory named pkgwithlgl which is the source of this "experimental" package (the directory's name correspond to package with LGL (Lemon Graph Library)).

Now, the main idea is to edit rcpp_hello_world.cpp (stored in the src) so to implement what I do here. More precisely, I change that file from this:

#include "rcpp_hello_world.h"

SEXP rcpp_hello_world(){
    using namespace Rcpp ;

    CharacterVector x = CharacterVector::create( "foo", "bar" )  ;
    NumericVector y   = NumericVector::create( 0.0, 1.0 ) ;
    List z            = List::create( x, y ) ;

    return z ;

into this:

#include "rcpp_hello_world.h"
#include <lemon/list_graph.h>
using namespace lemon ;

SEXP rcpp_hello_world(){
    using namespace Rcpp ;

    int res = 1;

    ListDigraph g;

    ListDigraph::Node u = g.addNode();
    ListDigraph::Node v = g.addNode();
    ListDigraph::Arc  a = g.addArc(u, v);

    int i = countNodes(g);
    int j = countArcs(g);

    Rprintf("num nodes is %d , and num edges is %d \n",i,j);

    return wrap(res) ;

Lets see what happens when I try to install the package. So in a linux console in the container directory of pkgwithlgl I run:

$ R CMD INSTALL pkgwithlgl
* installing to library ‘/home/juan/R/x86_64-pc-linux-gnu-library/2.12’
* installing *source* package ‘pkgwithlgl’ ...
** libs
g++ -I/usr/share/R/include   -I"/usr/local/lib/R/site-library/Rcpp/include"   -fpic  -O3 -pipe  -g -c rcpp_hello_world.cpp -o rcpp_hello_world.o
g++ -shared -o rcpp_hello_world.o -L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib -L/usr/lib64/R/lib -lR
installing to /home/juan/R/x86_64-pc-linux-gnu-library/2.12/pkgwithlgl/libs
** R
** preparing package for lazy loading
** help
Warning: /home/juan/Desktop/facu/investigacion_ensayos/Cosas_crudas/programming_coding/R-work-space/integrating_R_with_cpp_via_Rcpp/using_packages/pkgwithlgl/man/pkgwithlgl-package.Rd:32: All text must be in a section
Warning: /home/juan/Desktop/facu/investigacion_ensayos/Cosas_crudas/programming_coding/R-work-space/integrating_R_with_cpp_via_Rcpp/using_packages/pkgwithlgl/man/pkgwithlgl-package.Rd:33: All text must be in a section
*** installing help indices
  converting help for package ‘pkgwithlgl’
    finding HTML links ... done
    pkgwithlgl-package                      html  
    rcpp_hello_world                        html  
** building package indices ...
** testing if installed package can be loaded

* DONE (pkgwithlgl)

so It seems that the package was installed. Lets se if it works:

> require("pkgwithlgl")
Loading required package: pkgwithlgl
Loading required package: Rcpp
> rcpp_hello_world()
num nodes is 2 , and num edges is 1
[1] 1

It works !!!

Now I'm answering myself. What happens if I upload this package to (forexample) the CRAN repository and other one install it (without the installation of the LGL package). Will it work this package to him?

TODO: Answer that question.

Salut !