1

I am trying to call my R function from C++ program.

rtest = function(input ,output) {
  a <- input
  b <- output 
  outpath <- a+b
  print(a+b)
  return(outpath)
}

This is my R function. I need to find a way for calling this function from C with passing arguments. calling a R function from python code with passing arguments. Here i have made similar method for calling R from python. So i need to specify the path to R script and the name of the function, and also able to pass the arguments through python. I am looking for similar way in C. But didn't get results. This may be a simple thing. Any help is appreciated.

1 Answer 1

5

This question has multiple interpretations, which is why I did not attempt an answer before. Here Solutions for several possible interpretations:

C++ function defined with Rcpp that is called from R and uses a user defined R function. This follows http://gallery.rcpp.org/articles/r-function-from-c++/:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector callFunction(NumericVector x, NumericVector y, Function f) {
  NumericVector res = f(x, y);
  return res;
}

/*** R
set.seed(42)
x <- rnorm(1e5)
y <- rnorm(1e5)

rtest <- function(x, y) {
  x + y
}

head(callFunction(x, y, rtest))
head(x + y)
*/

The R function rtest is defined in R and passed to the C++ function callFunction together with it's two arguments. Partial result from Rcpp::sourceCpp():

> head(callFunction(x, y, rtest))
[1]  0.95642325 -0.57197358 -1.45084989 -0.18220091  0.07592864  0.56367202

> head(rtest(x, y))
[1]  0.95642325 -0.57197358 -1.45084989 -0.18220091  0.07592864  0.56367202

Calling the function in R and via C++ gives the same result.

C++ program using RInside which calls an user defined R function on data present in C++. Here we have two possibilities: either transfer the data to R and call the function there or move the function to C++ and call the R function in C++ like above:

#include <RInside.h>

int main(int argc, char *argv[]) {
    // define two vectors in C++
    std::vector<double> x({1.23, 2.34, 3.45});
    std::vector<double> y({2.34, 3.45, 1.23});
    // start R
    RInside R(argc, argv);
    // define a function in R
    R.parseEvalQ("rtest <- function(x, y) {x + y}");
    // transfer the vectors to R
    R["x"] = x;
    R["y"] = y;
    // call the function in R and return the result
    std::vector<double> z = R.parseEval("rtest(x, y)");
    std::cout << z[0] << std::endl;

    // move R function to C++
    Rcpp::Function rtest((SEXP) R.parseEval("rtest"));
    // call the R function from C++
    z = Rcpp::as<std::vector<double> >(rtest(x, y));
    std::cout << z[0] << std::endl;
    exit(0);
}

In order to compile this, I am using the GNUmakefile that comes with the examples in RInside. Result:

$ make -k run
ccache g++ -I/usr/share/R/include -I/usr/local/lib/R/site-library/Rcpp/include -I/usr/local/lib/R/site-library/RInside/include -g -O2 -fdebug-prefix-map=/home/jranke/git/r-backports/stretch/r-base-3.5.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -Wno-ignored-attributes -Wall    call_function.cpp  -Wl,--export-dynamic -fopenmp -Wl,-z,relro -L/usr/lib/R/lib -lR -lpcre -llzma -lbz2 -lz -lrt -ldl -lm -licuuc -licui18n  -lblas -llapack  -L/usr/local/lib/R/site-library/RInside/lib -lRInside -Wl,-rpath,/usr/local/lib/R/site-library/RInside/lib -o call_function

Running call_function:
3.57
3.57
Sign up to request clarification or add additional context in comments.

7 Comments

I was looking for this type of method. But still facing some <Rcpp> import error even after specifying the location of header. Thanks
@9113303 Are you using the same command line as I or are you using the referenced Makefile?
Thanks. This gnu makefile works for me. But ccache didnt works. But still i have 1 more doubt x+y (1.23+2.34) gives the first value 3.57, what about the other one,
It is not surprising that the command-line from my system does not work for you. Fortunately these system differences can be abstracted away, e.g. with that Makefile. As for the second 3.57: The rtest function is called twice and the output is therefore printed twice. You can look at previous revisions of this answer were I used different functions.
@gpier You will need the variables declared in the C++ code. The actual data might also come from command-line arguments, file input, ...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.