9

I was trying to call the sd(x), which is a R function, in Rcpp. I've seen an example of calling the R function dbate(x) in Rcpp and it works perfectly.

// dens calls the pdf of beta distribution in R
//[[Rcpp::export]]
double dens(double x, double a, double b)
{
    return R::dbeta(x,a,b,false);
}

But when I tired to apply this method to sd(x) as following, it went wrong.

// std calls the sd function in R
//[[Rcpp::export]]
double std(NumericVector x)
{
  return R::sd(x);
}

Does anyone know why this doesn't work?

Yuge Hao
  • 145
  • 1
  • 5
  • Can you provide the error message ? – digEmAll Jun 24 '16 at 15:37
  • Yes! It has several error messages: redefinition of 'std' as a different kind of symbol; no member named 'sd' in namespace 'R'; did you mean simply 'sd'? unexpected namespace 'std': expected expression – Yuge Hao Jun 24 '16 at 15:41
  • 3
    Anyway, this approach should work --> http://stackoverflow.com/questions/36594628/call-a-function-from-c-via-environment-rcpp – digEmAll Jun 24 '16 at 15:43
  • Thank you! Looks like I can learn another way to make this work! – Yuge Hao Jun 24 '16 at 15:48

1 Answers1

16

There are a few issues with your code.

  1. std is related to the C++ Standard Library namespace
    • This is triggering:

      error: redefinition of 'std' as different kind of symbol

  2. The R:: is a namespace that deals with Rmath functions. Other R functions will not be found in within this scope.
  3. To directly call an R function from within C++ you must use Rcpp::Environment and Rcpp::Function as given in the example sd_r_cpp_call().
    • There are many issues with this approach though including but not limited to the loss of speed.
  4. It is ideal to use Rcpp sugar expressions or implement your own method.

With this being said, let's talk code:

#include <Rcpp.h>

//' @title Accessing R's sd function from Rcpp
// [[Rcpp::export]]
double sd_r_cpp_call(const Rcpp::NumericVector& x){

  // Obtain environment containing function
  Rcpp::Environment base("package:stats"); 

  // Make function callable from C++
  Rcpp::Function sd_r = base["sd"];    

  // Call the function and receive its list output
  Rcpp::NumericVector res = sd_r(Rcpp::_["x"] = x,
                                 Rcpp::_["na.rm"]  = true); // example of additional param

  // Return test object in list structure
  return res[0];
}


// std calls the sd function in R
//[[Rcpp::export]]
double sd_sugar(const Rcpp::NumericVector& x){
  return Rcpp::sd(x); // uses Rcpp sugar
}

/***R
x = 1:5
r = sd(x)
v1 = sd_r_cpp_call(x)
v2 = sd_sugar(x)

all.equal(r,v1)
all.equal(r,v2)
*/
coatless
  • 20,011
  • 13
  • 69
  • 84