This question already has an answer here:
calling a user-defined R function from C++ using Rcpp
(1 answer)
Closed 6 years ago.
I have a package X in R. The package has a function foo(). I want to call the function foo() in a cpp file (using Rcpp). Is it possible?
#include <Rcpp.h>
void function01() {
// call foo() from package X ??
}
This is sort of a duplicate. Though, the majority of cases do not involve calling from a user defined package.
As a result, the mold to use is:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void function01(){
// Obtain environment containing function
Rcpp::Environment package_env("package:package_name_here");
// Make function callable from C++
Rcpp::Function rfunction = package_env["function_name"];
// Call the function and receive output (might not be list)
Rcpp::List test_out = rfunction(....);
}
Related
I wish to do calculations on elements of a vector using Rcpp, but the vector is getting so large (~60 GB) that I'm resorting to memory mapping it using the mmap package, but now it's the wrong type for my Rcpp function. Can this be overcome?
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double testRcpp(NumericVector input, int index) {
return input(index);
}
/*** R
writeBin(seq(0,1,1e-6),"test.bin")
bigvector1 <- seq(0,1,1e-6)
bigvector2 <- mmap("test.bin",mode=double())
testRcpp(bigvector1,3)
testRcpp(bigvector2,3) #"Not compatible with requested type: [type=environment; target=double]"
*/
Since the mmap function in r returns an object with type=environment write bigvector2[] instead of bigvector2 to use its elements. Basically replace
testRcpp(bigvector2,3)
to
testRcpp(bigvector2[],3)
If you want to try using mmap in the cpp part of Rcpp in windows you can use my repo from https://github.com/CoderRC/libmingw32_extended .
How can Rcpp::wrap and Rcpp::as methods be written for classes that contain an Rcpp class?
For example, the following .cpp file compiles using sourceCpp():
#include <Rcpp.h>
namespace Rcpp {
class myVector {
public:
NumericVector data;
myVector(NumericVector v) : data(v) {};
};
template <> myVector as(SEXP v) {
return myVector(v);
}
template <> SEXP wrap(const myVector& v) {
return v.data;
}
}
//[[Rcpp::export]]
Rcpp::myVector test(Rcpp::myVector& x){
return x;
}
In this example, we create a vector that is comprised simply of a single Rcpp class (NumericVector) and an Rcpp::as and Rcpp::wrap method so that it can be used as an argument in any exported function.
However, the code does not pass when creating an Rcpp package as follows:
Rstudio -> New Project -> New Directory -> R package using Rcpp
Copy above script into new file, test.cpp
Build -> Install and Restart
There are no complaints about the test.cpp but there are complaints in src/RcppExports.cpp. Here's the relevant function:
// test
Rcpp::myVector test(Rcpp::myVector& x);
RcppExport SEXP _test_test(SEXP xSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< Rcpp::myVector& >::type x(xSEXP);
rcpp_result_gen = Rcpp::wrap(test(x));
return rcpp_result_gen;
END_RCPP
}
The errors are:
Line 19: `myVector` does not name a type;
Line 24: `myVector` was not declared in this scope
... template argument 1 invalid, qualified-id in declaration, 'x' not declared, 'test' not declared... side-effects of above two errors.
I do know how to write Rcpp::as and Rcpp::wrap for classes that do NOT contain Rcpp classes (templated case, general case):
#include <RcppCommon.h>
Forward-declaration of class, may depend on C++ libraries (not Rcpp.h)
#include <Rcpp.h>
Unfortunately, Rcpp::myVec requires Rcpp.h and thus cannot be declared prior to including Rcpp.h.
Can external classes containing Rcpp classes make use of Rcpp::wrap and Rcpp::as? If so, is there any precedent I can view for details? I haven't found any despite quite a bit of searching, or maybe I'm overlooking something very simple.
I'm quite new to Rcpp. Sorry If I'm missing something obvious.
but when I try to use an igraph function in Rcpp I face the following obvious error on the left:
"Cannot initialize a Variable of type 'RCPP:Environment' (aka,'int') with an lvalue of type 'const char[15]'
Here is the code
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector insideOfCommEdgeIdsCpp(CharacterVector g, CharacterVector v) {
Environment igraph("package:igraph");
Function game_er = igraph["erdos.renyi.game"];
Function get_adjacency = igraph["get.adjacency"];
}
A few small errors in your file:
declared as NumericVector but nothing is returned
Environment igraph not set up correctly.
A corrected version is below. And it it worth repeating this: Any R functions called from C++ are still R functions that run at the speed of R functions.
Corrected code
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
using namespace Rcpp;
// [[Rcpp::export]]
void insideOfCommEdgeIdsCpp(CharacterVector g, CharacterVector v) {
Environment igraph = Environment("package:igraph");
Function game_er = igraph["erdos.renyi.game"];
Function get_adjacency = igraph["get.adjacency"];
}
This question already has answers here:
Call a function from c++ via environment Rcpp
(2 answers)
Closed 6 years ago.
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?
There are a few issues with your code.
std is related to the C++ Standard Library namespace
This is triggering:
error: redefinition of 'std' as different kind of symbol
The R:: is a namespace that deals with Rmath functions. Other R functions will not be found in within this scope.
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.
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)
*/
I have an R code with a bunch of user-defined R functions. I'm trying to make the code run faster and of course the best option is to use Rcpp. My code involves functions that call each other. Therefore, If I write some functions in C++, I should be able to call and to run some of my R functions in my c++ code. In a simple example consider the code below in R:
mySum <- function(x, y){
return(2*x + 3*y)
}
x <<- 1
y <<- 1
Now consider the C++ code in which I'm trying to access the function above:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int mySuminC(){
Environment myEnv = Environment::global_env();
Function mySum = myEnv["mySum"];
int x = myEnv["x"];
int y = myEnv["y"];
return wrap(mySum(Rcpp::Named("x", x), Rcpp::Named("y", y)));
}
When I source the file in R with the inline function sourceCpp(), I get the error:
"invalid conversion from 'SEXPREC*' to int
Could anyone help me on debugging the code? Is my code efficient? Can it be summarized? Is there any better idea to use mySum function than what I did in my code?
Thanks very much for your help.
You declare that the function should return an int, but use wrap which indicates the object returned should be a SEXP. Moreover, calling an R function from Rcpp (through Function) also returns a SEXP.
You want something like:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
SEXP mySuminC(){
Environment myEnv = Environment::global_env();
Function mySum = myEnv["mySum"];
int x = myEnv["x"];
int y = myEnv["y"];
return mySum(Rcpp::Named("x", x), Rcpp::Named("y", y));
}
(or, leave function return as int and use as<int> in place of wrap).
That said, this is kind of non-idiomatic Rcpp code. Remember that calling R functions from C++ is still going to be slow.