Sources

What is RCpp and why should I care?

Definition

“The RCpp package provides a consistent API for seamlessly accessing, extending or modifying R objects at the C++ level” - Eddelbuttel and Francois.

API

a set of functions and procedures allowing the creation of applications that access the features or data of an operating system, application, or other service.

  • One of the most widely used R extensions (over 1000 packages)
  • With very minimal knowledge of C++ you can speed up function runs A LOT
  • The most efficient R functions are written in C++ and called from R

Writing C++ functions in R

  • You can write C++ functions inline in your R code using cppFunction
  • You can also compile single lines of code directly using evalCpp

In R script or console:

library(Rcpp)
cppFunction('int add(int x, int y, int z) {
  int sum = x + y + z;
  return sum;
}')
# add works like a regular R function
add
## function (x, y, z) 
## .Call(<pointer: 0x7fd174a9b530>, x, y, z)
add(1, 2, 3)
## [1] 6
evalCpp( "std::numeric_limits<double>::max()" )
## [1] 1.797693e+308

Calling C++ from R

mean.cpp

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
double meanC(NumericVector x) {
  int n = x.size();
  double total = 0;

  for(int i = 0; i < n; ++i) {
    total += x[i];
  }
  return total / n;
}
  • #include <Rcpp.h> allows you to call Rcpp syntax in the file. You can omit using namespace Rcpp if you use :: i.e. Rcpp::NumericVector
  • // [[Rcpp::export]] - put this above any function you want to make available in R
  • NumericVector, .size() useful type, function implemented in Rcpp
# code can be saved in .cpp file and sourced:
# sourceCpp("mean.cpp")

# code can be sourced directly
src <- 
"#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
double meanC(NumericVector x) {
  int n = x.size();
  double total = 0;

  for(int i = 0; i < n; ++i) {
    total += x[i];
  }
  return total / n;
}
"
sourceCpp(code = src)
library(microbenchmark)
x <- runif(1e5)
microbenchmark(
  mean(x),
  meanC(x)
)
## Unit: microseconds
##      expr     min       lq     mean  median      uq       max neval
##   mean(x) 414.193 416.0415 421.4565 417.770 424.888   506.255   100
##  meanC(x) 371.513 372.0395 482.2166 372.425 381.026 10998.444   100
  • sourceCpp compiles the file
  • More Rcpp syntax here

Typing and methods

Rcpp Types

  • Scalar classes
    • int
    • double
    • bool
    • String
  • Vector classes
    • IntegerVector
    • NumericVector
    • LogicalVector
    • CharacterVector

Rcpp methods

  • Static methods (called with :: on class)
  • Member functions or methods (called with . on object)
src <- 
  "#include <Rcpp.h>
  using namespace Rcpp; 

  // [[Rcpp::export]]
  NumericVector fun(){
    //create new vector of size 3
    NumericVector v = NumericVector::create(1,2,3);
    Rcout << NumericVector::get_na() << std::endl;
    
    //operate on object v
    Rcout << v.size() << std::endl;
    //append a new value to the vector
    v.push_back(4);
  
    return v;
  }
"

sourceCpp(code = src)
fun()
## nan
## 3
## [1] 1 2 3 4

Rcpp modules

RCPP_MODULE(unif_module) {
class_<Uniform>("Uniform")
.constructor<double,double>()
.field("min", &Uniform::min, "minimum value")
.field("max", &Uniform::max, "maximum value")
.method("draw", &Uniform::draw)
;
}
  • You can expose these using the Rcpp macro RCPP_MODULE
  • the class_<Uniform> constructor argument is what we will call the class from R
  • .field, .constructor, .method, .property
  • .field can be used with two or three arguments
  • .field_readonly prevents it from being modified from R