When you are learning to wrap compiled code in an R package, the hardest part is rarely the idea. It is the dozen small mechanical details that have to line up before anything compiles: where the header goes, what the Makevars flag is called, how the attribute is spelled, which file the generator writes. A full production package buries those details under everything else it is doing, and a documentation page describes them without letting you build them.
The R&D Rcpp collection takes the opposite approach. It is a set of minimal, complete, buildable R packages that each demonstrate exactly one technique for getting compiled code to talk to R. Every package is small enough to read in a sitting, passes R CMD check, and ships with continuous integration so you can see it building. When you are stuck on one specific thing, you can clone the example that does just that thing and nothing else.
The collection began in 2015 with a couple of header-layout examples and has grown over the years into a small library of patterns. The source lives under the coatless-rd-rcpp GitHub organization, and each package has a rendered site at rd-rcpp.thecoatlessprofessor.com/<package>/. This post is the map. Each entry below links to a write-up of the example and to its source.
Getting compiled code into a package
The starting point: how do you call a routine written in another language from R?
- Combining a C Routine with Rcpp calls a hand-written C routine, one that uses R’s C API directly, from inside an Rcpp function, with a pure-Rcpp version alongside for comparison.
- Calling a Fortran Routine from Rcpp bridges Fortran and C++ with
iso_c_bindingso the two languages agree on symbol names and argument types. - Remapping C’s printf() to R’s Rprintf() shows how to redirect a C library’s console output into R so it can be captured.
Organizing the source
Once you have more than one file, where does it all go?
- Embedding Multiple Code Files in src/ with Headers separates compiled code into individual units connected by header files.
- Embedding Compiled Code in Subdirectories of src/ goes a step further, using a
Makevarsfile to compile sources nested in subdirectories. - Sharing C++ Functions Between R Packages packages header-only C++ functions in one package so another package can link against them.
- Selecting a C++ Standard for an R Package pins the C++ standard a package compiles against through the
CXX_STDfield.
Exposing C++ types to R
Moving richer objects, not just numbers, across the boundary.
- Exposing a BankAccount C++ Class with Rcpp Modules and Exposing a Student C++ Class with Rcpp Modules surface whole C++ classes into R with Rcpp Modules.
- Custom as and wrap Converters for a C++ Type teaches Rcpp how to convert a user-defined struct to and from an R object so it can be used as a function argument and return type.
Parallel and concurrent computing
Putting more than one core to work, correctly.
- Using OpenMP with Rcpp parallelizes a C++ routine with OpenMP directly inside Rcpp, and Using OpenMP with a C Routine and Rcpp does the same when the parallel loop lives in a C file.
- Using OpenMP with cpp11 repeats the OpenMP example with the lighter-weight
cpp11package in place of Rcpp. - Calling an Rcpp Function with a doParallel Backend packages a C++ function so it can run inside a
foreachparallel region, and Calling an Rcpp Function with a mirai Backend distributes a packaged kernel acrossmiraidaemons. - Independent Parallel RNG Streams with dqrng tackles the subtle one: giving each thread its own reproducible, non-overlapping random number stream.
Using the examples
Every package installs the same way. With a compiler in hand:
# install.packages("remotes")
remotes::install_github("coatless-rd-rcpp/<package>")From there, read the source, run R CMD check, and adapt the one piece you need. If you spot a gap in the collection or a pattern worth adding, the repositories are open at github.com/coatless-rd-rcpp.