Reputation: 683
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) {
double* ans = malloc(sizeof(double)*n);
for (int i = 0; i < n; ++i)
ans[i] = vector[i] + 1
return ans;
}
in the context:
x = 1:3
x = addOneToVector(x)
x # 2, 3, 4
Upvotes: 8
Views: 9845
Reputation: 683
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):
Create function that will only take pointers to basic types and do everything by side-effects (returns void). eg in a file called foo.c
:
void addOneToVector(int* n, double* vector) {
for (int i = 0; i < *n; ++i)
vector[i] += 1.0;
}
Compile file C source as dynamic library, you can use R shortcut to do this:
$ R CMD SHLIB foo.c
This will then create a file called foo.so
on Mac or foo.dll
on Windows.
Load dynamic library from R
on Mac:
dyn.load("foo.so")
or on Windows:
dyn.load("foo.dll")
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/
Upvotes: 11
Reputation: 1
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!
Upvotes: 0
Reputation: 5254
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.
Upvotes: 3