How to call C function from R?

后端 未结 3 2010
梦毁少年i
梦毁少年i 2020-12-09 06:45

How can you use some function written in C from R level using R data. eg. to use function like:

double* addOneToVector(int n, const double* vector) {
    dou         


        
相关标签:
3条回答
  • 2020-12-09 07:24

    I've searched stackoverflow first but I noticed there is no answer for that in here.
    The general idea is (commands for linux, but same idea under other OS):

    1. Create function that will only take pointers to basic types and do everything by side-effects (returns void). eg:

      void addOneToVector(int* n, double* vector) {
          for (int i = 0; i < *n; ++i)
              vector[i] += 1.0;
      }
      
    2. Compile file C source as dynamic library, you can use R shortcut to do this:

      $ R CMD SHLIB lib.c
      
    3. Load dynamic library from R:

      dyn.load("foo.so")
      
    4. Call C functions using .C R function, IE:

      x = 1:3
      ret_val = .C("addOneToVector", n=length(x), vector=as.double(x))
      

    It returns list from which you can get value of inputs after calling functions eg.

    ret_val$x # 2, 3, 4
    

    You can now wrap it to be able to use it from R easier.

    There is a nice page describing whole process with more details here (also covering Fortran):

    http://users.stat.umn.edu/~geyer/rc/

    0 讨论(0)
  • 2020-12-09 07:28

    I just did the same thing in a very simple way using the Rcpp package. It allows you to write C++ functions directly in R.

    library("Rcpp")
    cppFunction("
    NumericVector addOneToVector(NumericVector vector) {
      int n = vector.size();
    
      for (int i = 0; i < n; ++i)
        vector[i] = vector[i] + 1.0;
    
      return vector;
    }")
    

    Find more details here http://adv-r.had.co.nz/Rcpp.html. C++ functions can be done very fast with these instructions.

    0 讨论(0)
  • 2020-12-09 07:30

    First off, I wanted to thank both @m0nhawk and @Jan for their immensely useful contributions to this problem.

    I tried both methods on my MacBook: first the one showed m0nhawk which requires creating a function in C (without the main method) and then compiling using R CMD SHLIB <prog.c> and then invoking the function from R using the .C command

    Here's a small C code I wrote (not a pro in C - just learning in bits and pieces)

    Step 1: Write the C Program

    #include <stdio.h>
    int func_test() {
        
        for(int i = 0; i < 5; i++) {
            printf("The value of i is: %d\n", i);
        }
        return 0;
    
    }
    

    Step 2: Compile the program using

    R CMD SHLIB func_test.c
    

    This will produce a func_test.so file

    Step 3: Now write the R Code that invokes this C function from within R Studio

    dyn.load("/users/my_home_dir/xxx/ccode/ac.so")
    .C("func_test")
    

    Step 4: Output:

    .C("func_test") The value of i is: 0 The value of i is: 1 The value of i is: 2 The value of i is: 3 The value of i is: 4 list()

    Then I tried the direct method suggested by Jan - using the RCpp package

    library("Rcpp")
    cppFunction("
    NumericVector addOneToVector(NumericVector vector) {
      int n = vector.size();
    
      for (int i = 0; i < n; ++i)
        vector[i] = vector[i] + 1.0;
    
      return vector;
    }")
    
    # Test code to test the function
    addOneToVector(c(1,2,3))
    

    Both methods worked superbly. I can now start writing functions in C or C++ and use them in R

    Thank you once again!

    0 讨论(0)
提交回复
热议问题