0% found this document useful (0 votes)
112 views4 pages

RCPP Quickref PDF

This document provides a quick reference guide for using Rcpp to interface R and C++. It gives short code snippets for creating vectors and matrices in C++, accessing and modifying their elements, and using STL functions. It also provides examples of how to compile C++ code directly in R using cppFunction, interface C++ and R by defining C++ functions for use in R with Rcpp attributes, and build an R package with Rcpp.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
112 views4 pages

RCPP Quickref PDF

This document provides a quick reference guide for using Rcpp to interface R and C++. It gives short code snippets for creating vectors and matrices in C++, accessing and modifying their elements, and using STL functions. It also provides examples of how to compile C++ code directly in R using cppFunction, interface C++ and R by defining C++ functions for use in R with Rcpp attributes, and build an R package with Rcpp.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 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 November 8, 2019

This document provides short code snippets that are helpful for using the // set single values
Rcpp (Eddelbuettel et al., 2019; 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 | November 8, 2019 | 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 ); // Special environments
NumericVector yy = floor( y ); Environment::Rcpp_namespace();
Environment::base_env();
NumericVector xx = exp( x ); Environment::base_namespace();
NumericVector yy = exp( y ); Environment::global_env();
Environment::empty_env();
NumericVector xx = head( x, 2 );
IntegerVector yy = head( y, 2 ); // Obtain an R environment
Environment stats("package:stats");
IntegerVector xx = seq_len( 10 ); Environment env( 2 ); // by position
IntegerVector yy = seq_along( y ); Environment glob = Environment::global_env();

Eddelbuettel and François Rcpp Vignette | November 8, 2019 | 3


// Extract function from specific environment class Bar {
Function rnorm = stats["rnorm"]; public:
Bar(double x_) : x(x_), nread(0), nwrite(0) {}
// Assign into the environment
glob["x"] = "foo"; double get_x( ) {
glob["y"] = 3; nread++;
return x;
// Retrieve information from environment }
std::string x = glob["x"];
glob.assign( "foo" , 3 ); void set_x( double x_) {
int foo = glob.get( "foo" ); nwrite++;
int foo = glob.find( "foo" ); x = x_;
CharacterVector names = glob.ls(TRUE) }
bool b = glob.exists( "foo" );
glob.remove( "foo" ); IntegerVector stats() const {
return
// Administration IntegerVector::create(_["read"] = nread,
glob.lockBinding("foo"); _["write"] = nwrite);
glob.unlockBinding("foo"); }
bool b = glob.bindingIsLocked("foo"); private:
bool b = glob.bindingIsActive("foo"); double x; int nread, nwrite;
};
// Retrieve related environments
Environment e = stats.parent(); RCPP_MODULE(mod_bar) {
Environment e = glob.new_child(); class_<Bar>( "Bar" )
.constructor<double>()
.property( "x", &Bar::get_x, &Bar::set_x,
Calling Functions in R
"Docstring for x" )
// Do NOT expect to have a performance gain .method( "stats", &Bar::stats,
// when calling R functions from R! "Docstring for stats")
;}
// Retrieve functions from default loaded env.
Function rnorm("rnorm"); /*** R
rnorm(100, _["mean"] = 10.2, _["sd"] = 3.2 ); ## The following is R code.
require(mypackage) s
// Passing in an R function and obtaining results how(Bar)
// Make sure function conforms with return type! b <- new(Bar, 10)
NumericVector callFunction(NumericVector x, b$x <- 10
Function f) { b_persist <- list(stats=b$stats(), x=b$x)
NumericVector res = f(x); rm(b)
return res; */
}
References
/*** R
Eddelbuettel D (2013). Seamless R and C++ Integration with Rcpp. Use R!
# The following is R code executed Springer, New York. ISBN 978-1-4614-6867-7.
# by sourceCpp() as a convenience. Eddelbuettel D, François R (2011). “Rcpp: Seamless R and C++ Integration.”
x = 1:5 Journal of Statistical Software, 40(8), 1–18. URL http://www.jstatsoft.org/v40/
callFunction(x, sum) i08/.
*/ Eddelbuettel D, François R, Allaire J, Ushey K, Kou Q, Russel N, Chambers J,
Bates D (2019). Rcpp: Seamless R and C++ Integration. R package version
1.0.3, URL http://CRAN.R-Project.org/package=Rcpp.
Modules

// Warning -- Module-based objects do not persist


// across quit(save="yes")/reload cycles. To be
// safe, save results to R objects and remove
// module objects before exiting R.

// To create a module-containing package from R:


// Rcpp.package.skeleton("mypackage", module=TRUE)

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

You might also like