I just started learning R, thus getting stuck with trivial looking issues. I am trying to figure out how values are outputted in R. In C++ we simply use return variable, but that doesn't seem to be the case with R. Say I have a function that takes 4 input arguments, passes those arguments to a c++ function which does the required calculations, now if I want to load this myfun in R and get output from the c++ funciton, what do I need to do? Following is the template I am trying to use.
extern "C" {
SEXP myfun(SEXP S, SEXP A, SEXP B, SEXP C) { //will call this function from R.
SEXP rate, dir, list, list_names; //declare variables
PROTECT( rate = allocMatrix(REALSXP, 10, 2) ); //allocate 10x2 matrix of double type?
PROTECT( dir = allocVector(INTSXP, 10) ); //allocated vector(10) of int type?
double* p_rate = REAL(rate); //why do I need pointers?
int* p_dir = INTEGER(dir);
//here I call a C++ function which calculates vector<vector<double> > someVal
and vector<int> someVal2
.
Now I want to pass those values to the rate and dir.
for(int i =0; i < 10; i++){
rate[i][0] = someVal1[i][0];
rate[i][1] = someVal1[i][1];
dir[i] = someVal2[i];
}
but the compiler doesn't like it. I am not sure how to use the p_rate and p_dir pointers in this case.
Also, I am not quite understand why the following code is the way it is. It seems to be passing the strings, rate and dir to the list_names and values to the rate and dir. Why can't we simply do cout and print the desired values?
char *tag[2] = {"rate","dir"};
PROTECT(list_names = allocVector(STRSXP ,2));
SET_STRING_ELT(list_names, 0, mkChar(tag[0]));
SET_STRING_ELT(list_names, 1, mkChar(tag[1]));
PROTECT(list = allocVector(VECSXP ,2));
SET_VECTOR_ELT(list, 0, rate);
SET_VECTOR_ELT(list, 1, dir);
setAttrib(list, R_NamesSymbol , list_names);
UNPROTECT(8);
return (list);
}
I am not getting the basic idea behind returning the variables in R, it seems very confusing. I would really appreciate if someone could point me to the appropriate resources that explains these stuffs.
Thanks for your help in advance!
A SEXP is a variant type, with subtypes for all R's data structures. The most important types are: REALSXP : numeric vector. INTSXP : integer vector. LGLSXP : logical vector.
If you are already familiar with C++, you may find our Rcpp project for seamless R and C++ integrarion useful. It contains a lot of documentation and examples, plus CRAN has now over 80 packages using it which provides another large corpus of examples.
You could start with "Introduction" vignette which corresponds to our JSS paper, and also peruse the [rcpp]
tag here.
Otherwise, you are back at the R API which is more bare-bones and based on C only.
As we said while answering your previous question, give Rcpp a shot, and take away all the kludge in your code.
#include <Rcpp.h>
using namespace Rcpp ;
void yourCode( std::vector< std::vector<double> >& someVal,
std::vector<double>& someVal2 ){ ... }
extern "C" SEXP myfun() {
NumericMatrix rate(10, 2);
NumericVector dir(10) ;
std::vector< std::vector<double> > someVal ;
std::vector< double > someVal2 ;
// call whatever function that fills someVal and someVal2
yourCode( someVal, someVal2 ) ;
// fills rate and dir
for(int i =0; i < 10; i++){
rate(i, 0) = someVal1[i][0];
rate(i, 1) = someVal1[i][1];
dir[i] = someVal2[i];
}
// structure the output
List result = List::create(
_["rate"] = rate,
_["dir"] = dir
) ;
return result ;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With