Site icon R-bloggers

05.05.09: 6 Steps to call a C function in R

[This article was first published on B.I.S. dato, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Tasks
After some searching and testing, I have began to know how to call a C function in R. The reason for doing this can be speed (for example, the convolution of two finite sequences, as raised by the Writing R Extensions tutorial, refered as ‘WRE tutorial’), or existing codes that have been implemented in C or Fortran (e.g., mfinder software source codes kindly provided by Nadav Kashtan, Uri Alon and their colleagues. One may argue that auto-wrapping tools like SWIG (Simplified Wrapper and Inteface Generator) could do this automatically. However it is worth implementing by hand at least in two scenarios:
To call a C function in R, one has to following following steps:
  1. Write a function in C, for example a toy example of function ‘myC’.
    void myC(int* lower, int* upper) {
     int i;
     printf("\t Number \t\t Sqaure Root of the Number\n");
     for(i = *lower; i<= *upper; ++i)     
       printf("\t %d \t\t\t %2.2f \n",i, sqrt((double) i));  
    }
  2. Create shared objects of the function myC with R CMD SHLIB myC.c in command line. If neccessary also provide needed parameters, for example -lm. This step produces a myC.so file, namely the shared object.
  3. Use dyn.load("myC.so") function in a R session to load the shared object.
  4. After loading, the function can be called with .C function, with the function name in string as the first parameter followed by parameters to be passed. Please keep in mind that the type of parameter must be checked (coerced) correct before passing, otherwise one may face unexpected results. use the toy function, a call to the function is demonstrated by:
    res <- .C("myC", lower=as.integer(0), upper=as.integer(8))
  5. Now you should see the output of the function, as follows:
      Number    Sqaure Root of the Number
      0     0.00 
      1     1.00 
      2     1.41 
      3     1.73 
      4     2.00 
      5     2.24 
      6     2.45 
      7     2.65 
      8     2.83 
  6. (Optionally) One could unload the shared library by dyn.unload("myC.so").
Some words off-topic: now I think it is not that difficult, however it took me quite a long time to understand the (sometimes too detailed) descriptions in the R extension tutorial: I am not sure whether others have a similar feeling, I believe the quality of documentation in R needs to be improved, especially in the readability and approachability: two common scenario always trouble me: either there is no easy and understandable answer to a question (like the one I am discussing here), or I do not know there is a function in any package implementing a desired task (so called ‘re-use of the code’, preferred to write the code of his own).

Back to the topic, following the procedures described above, one can relative easily wrap a C (or other languages, like Fortran or C++) function in R. The wrapping is desired since at least it may help the check/coerce of the types.

Next step is to embed one or more C files in a package, which normally requires the use of configure and Makevar files. There is also some words spent on this in the WRE tutorial, but to me they are not structured and I did not ‘know-how’ even after several times of reading. So next step I will also write a demo to show how to do this.

To leave a comment for the author, please follow the link and comment on their blog: B.I.S. dato.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.