Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

Rcpp Quick Reference Guide

Dirk Eddelbuettela and Romain Françoisb


a
http://dirk.eddelbuettel.com; b https://romain.rbind.io/

This version was compiled on September 24, 2017

This document provides short code snippets that are helpful for using the // set single values
Rcpp (Eddelbuettel et al., 2017; Eddelbuettel and François, 2011; Eddel- xx[0] = 2.1;
buettel, 2013). xx(1) = 4.2;
Rcpp | quickref | R | C++
yy["foo"] = 3.0;
Important Notes
// grow the vector
// If you experience compiler errors, please check yy["foobar"] = 10.0;
// that you have an appropriate version of g++.
// See ‘Rcpp-FAQ’ for more information. Using matrices

// Many of the examples here imply the following: // Initializing from SEXP,
#include <Rcpp.h> // dimensions handled automatically
using namespace Rcpp; SEXP x;
// The cppFunction will automatically add this. NumericMatrix xx(x);

// Or, prefix Rcpp objects with the Rcpp namespace // Matrix of 4 rows & 5 columns (filled with 0)
// as e.g. in: NumericMatrix xx(4, 5);
Rcpp::NumericVector xx(10);
// Fill with value
int xsize = xx.nrow() * xx.ncol();
Create simple vectors for (int i = 0; i < xsize; i++) {
xx[i] = 7;
SEXP x; std::vector<double> y(10);
}
// Same as above, using STL fill
// from SEXP
std::fill(xx.begin(), xx.end(), 8);
NumericVector xx(x);
// Assign this value to single element
// of a given size (filled with 0)
// (1st row, 2nd col)
NumericVector xx(10);
xx(0,1) = 4;
// ... with a default for all values
NumericVector xx(10, 2.0);
// Reference the second column
// Changes propagate to xx (same applies for Row)
// range constructor
NumericMatrix::Column zzcol = xx( _, 1);
NumericVector xx(y.begin(), y.end());
zzcol = zzcol * 2;
// using create
// Copy the second column into new object
NumericVector xx =
NumericVector zz1 = xx( _, 1);
NumericVector::create(1.0, 2.0, 3.0, 4.0);
// Copy submatrix (top left 3x3) into new object
NumericVector yy =
NumericMatrix zz2 = xx( Range(0,2), Range(0,2));
NumericVector::create(Named["foo"] = 1.0,
_["bar"] = 2.0);
// _ short for Named Inline C++ Compile in R

## Note - this is R code.


Extract and set single elements ## cppFunction in Rcpp allows rapid testing.
require(Rcpp)
// extract single values
double x0 = xx[0];
cppFunction("
double x1 = xx(1);
NumericVector exfun(NumericVector x, int i){
x = x*i;
double y0 = yy["foo"];
return x;
double y1 = yy["bar"];
}")

https://cran.r-project.org/package=Rcpp Rcpp Vignette | September 24, 2017 | 1–4


require(myPackage)
exfun(1:5, 3)
aa <- 1.5
## Use evalCpp to evaluate C++ expressions bb <- 1.5
evalCpp("std::numeric_limits<double>::max()") cc <- myfunR(aa, bb)
aa == bb
# FALSE, C++ modifies aa
Interface with R
First step in R. aa <- 1:2
bb <- 1:2
# In R, create a package shell. For details,
cc <- myfunR(aa, bb)
# see the "Writing R Extensions" manual and
identical(aa, bb)
# the "Rcpp-package" vignette.
# TRUE, R/C++ types don’t match
# so a copy was made
Rcpp.package.skeleton("myPackage")

# Add R code to pkg R/ directory. Call C++ STL interface


# function. Do type-checking in R.
// sum a vector from beginning to end
myfunR <- function(Rx, Ry) { double s = std::accumulate(x.begin(),
ret = .Call("myCfun", Rx, Ry, x.end(), 0.0);
package="myPackage") // prod of elements from beginning to end
return(ret) int p = std::accumulate(vec.begin(),
} vec.end(), 1,
std::multiplies<int>());
Additional C++. // inner_product to compute sum of squares
double s2 = std::inner_product(res.begin(),
// Add C++ code to pkg src/ directory.
res.end(),
using namespace Rcpp;
res.begin(), 0.0);
// Define function as extern with RcppExport
RcppExport SEXP myCfun( SEXP x, SEXP y) {
// If R/C++ types match, use pointer to x. Rcpp Attributes
// Pointer is faster, but changes to xx
// propagate to R ( xx -> x == Rx). In C++.
NumericVector xx(x); // Add code below into C++ file Rcpp_example.cpp
// clone is slower and uses extra memory. #include <Rcpp.h>
// Safe. No side effects. using namespace Rcpp;
NumericVector yy(clone(y));
// Place the ’Rcpp::export’ tag
xx[0] = yy[0] = -1.5; // right above function declaration.
int zz = xx[0];
// [[Rcpp::export]]
// use wrap() to return non-SEXP objects, e.g: double muRcpp(NumericVector x){
// return(wrap(zz)); int n = x.size(); // Size of vector
// Build and return a list double sum = 0; // Sum value
List ret;
ret["x"] = xx; // For loop, note cpp index shift to 0
ret["y"] = yy; for(int i = 0; i < n; i++){
return(ret); // Shorthand for sum = sum + x[i]
} sum += x[i];
}
On the command-line.

# From shell, above package directory return sum/n; // Obtain and return the Mean
R CMD build myPackage }
R CMD check myPackage_1.0.tar.gz ## Optional
R CMD INSTALL myPackage_1.0.tar.gz // Place dependent functions above call or
// declare the function definition with:
Back in R. double muRcpp(NumericVector x);

// [[Rcpp::export]]

2 | https://cran.r-project.org/package=Rcpp Eddelbuettel and François


double varRcpp(NumericVector x, bool bias = true){ NumericVector xx = rep( x, 3 );
// Calculate the mean using C++ function NumericVector xx = rep_len( x, 10 );
double mean = muRcpp(x); NumericVector xx = rep_each( x, 3 );
double sum = 0;
int n = x.size(); IntegerVector yy = rev( y );

for(int i = 0; i < n; i++){


Random Number Generation functions}
sum += pow(x[i] - mean, 2.0); // Square
} // Set seed
RNGScope scope;
return sum/(n-bias); // Return variance
} // For details see Section 6.7.1--Distribution
// functions of the ‘Writing R Extensions’ manual.
In R:. // In some cases (e.g. rnorm), dist-specific
Rcpp::sourceCpp("path/to/file/Rcpp_example.cpp") // arguments can be omitted; when in doubt,
x <- 1:5 // specify all dist-specific arguments. The use
all.equal(muRcpp(x), mean(x)) // of doublesrather than integers for dist-
all.equal(var(x),varRcpp(x)) // specific arguments is recommended. Unless
// explicitly specified, log=FALSE.

Rcpp Extensions // Equivalent to R calls


NumericVector xx = runif(20);
// Enable C++11 NumericVector xx1 = rnorm(20);
// [[Rcpp::plugins(cpp11)]] NumericVector xx1 = rnorm(20, 0);
NumericVector xx1 = rnorm(20, 0, 1);
// Enable OpenMP (excludes macOS)
// [[Rcpp::plugins(openmp)]] // Example vector of quantiles
NumericVector quants(5);
// Use the RcppArmadillo package for (int i = 0; i < 5; i++) {
// Requires different header file from Rcpp.h quants[i] = (i-2);
#include <RcppArmadillo.h> }
// [[Rcpp::depends(RcppArmadillo)]]
// in R, dnorm(-2:2)
NumericVector yy = dnorm(quants) ;
Rcpp sugar NumericVector yy = dnorm(quants, 0.0, 1.0) ;

NumericVector x = // in R, dnorm(-2:2, mean=2, log=TRUE)


NumericVector::create(-2.0,-1.0,0.0,1.0,2.0); NumericVector yy = dnorm(quants, 2.0, true) ;
IntegerVector y =
IntegerVector::create(-2, -1, 0, 1, 2); // Note - cannot specify sd without mean
// in R, dnorm(-2:2, mean=0, sd=2, log=TRUE)
NumericVector xx = abs( x ); NumericVector yy = dnorm(quants, 0.0, 2.0, true) ;
IntegerVector yy = abs( y );
// To get original R api, use Rf_*
bool b = all( x < 3.0 ).is_true() ; double zz = Rf_rnorm(0, 2);
bool b = any( y > 2 ).is_true();

NumericVector xx = ceil( x ); Environment


NumericVector xx = ceiling( x );
NumericVector yy = floor( y ); // Obtain an R environment
NumericVector yy = floor( y ); Environment stats("package:stats");
Environment env( 2 ); // by position
NumericVector xx = exp( x );
NumericVector yy = exp( y ); // Special environments
Environment::Rcpp_namespace();
NumericVector xx = head( x, 2 ); Environment::base_env();
IntegerVector yy = head( y, 2 ); Environment::base_namespace();
Environment::global_env();
IntegerVector xx = seq_len( 10 ); Environment::empty_env();
IntegerVector yy = seq_along( y );
// Extract function from specific environment

Eddelbuettel and François Rcpp Vignette | September 24, 2017 | 3


Function rnorm = stats["rnorm"]; // Warning -- Module-based objects do not persist
// across quit(save="yes")/reload cycles. To be
// Assign into the environment // safe, save results to R objects and remove
glob["x"] = "foo"; // module objects before exiting R.
glob["y"] = 3;
// To create a module-containing package from R:
// Retrieve information from environment // Rcpp.package.skeleton("mypackage", module=TRUE)
std::string x = glob["x"];
glob.assign( "foo" , 3 ); class Bar {
int foo = glob.get( "foo" );
int foo = glob.find( "foo" ); public:
CharacterVector names = glob.ls() Bar(double x_) : x(x_), nread(0), nwrite(0) {}
bool b = glob.exists( "foo" );
glob.remove( "foo" ); double get_x( ) {
nread++;
// Administration return x;
glob.lockBinding("foo"); }
glob.unlockBinding("foo");
bool b = glob.bindingIsLocked("foo"); void set_x( double x_) {
bool b = glob.bindingIsActive("foo"); nwrite++;
x = x_;
// Retrieve related environments }
Environment e = stats.parent();
Environment e = glob.new_child(); IntegerVector stats() const {
return
Calling Functions in R IntegerVector::create(_["read"] = nread,
_["write"] = nwrite);
// Do NOT expect to have a performance gain }
// when calling R functions from R! private:
double x; int nread, nwrite;
// Retrieve functions from default loaded env. };
Function rnorm("rnorm");
rnorm(100, _["mean"] = 10.2, _["sd"] = 3.2 ); RCPP_MODULE(mod_bar) {
class_<Bar>( "Bar" )
// Passing in an R function and obtaining results .constructor<double>()
// Make sure function conforms with return type! .property( "x", &Bar::get_x, &Bar::set_x,
NumericVector callFunction(NumericVector x, "Docstring for x" )
Function f) { .method( "stats", &Bar::stats,
NumericVector res = f(x); "Docstring for stats")
return res; ;}
}
/*** R
/*** R ## The following is R code.
# The following is R code executed require(mypackage) s
# by sourceCpp() as a convenience. how(Bar)
x = 1:5 b <- new(Bar, 10)
callFunction(x, sum) b$x <- 10
*/ b_persist <- list(stats=b$stats(), x=b$x)
rm(b)
*/
Modules

References i08/.
Eddelbuettel D, François R, Allaire J, Ushey K, Kou Q, Russel N, Chambers J,
Eddelbuettel D (2013). Seamless R and C++ Integration with Rcpp. Use R!
Bates D (2017). Rcpp: Seamless R and C++ Integration. R package version
Springer, New York. ISBN 978-1-4614-6867-7.
0.12.12, URL http://CRAN.R-Project.org/package=Rcpp.
Eddelbuettel D, François R (2011). “Rcpp: Seamless R and C++ Integration.”
Journal of Statistical Software, 40(8), 1–18. URL http://www.jstatsoft.org/v40/

4 | https://cran.r-project.org/package=Rcpp Eddelbuettel and François

You might also like