The Rcpp package provides a consistent API for seamlessly accessing, extending or modifying R objects at the C++ level. Rcpp supports implementing R functions in C++ for high performance computing and to easily interface R with external libraries.
The RStudio IDE has a number of features that support working with Rcpp, including:
- Syntax highlighting for C/C++
- Quick navigation to gcc errors and warnings
- Integrated editor support for
sourceCpp
- Tools for package development with Rcpp
Getting Started
If you are new to Rcpp, then the following resources provide a helpful introduction:
- Rcpp: Seamless R and C++ Integration
- Rcpp website: http://www.rcpp.org/
- Rcpp book: http://www.rcpp.org/book/
- Rcpp Quick Reference Guide
- High performance functions with Rcpp
- Introduction to Rcpp Attributes
- Gallery of examples: http://gallery.rcpp.org/
Before beginning you should also ensure that you have installed all prerequisites for working with Rcpp, including:
- GNU software development tools including a C/C++ compiler; and
- LaTeX for building R manuals and vignettes (only required for package development)
If you don't already have these tools installed on your system please consult the article on Package Development Prerequisites for additional details on how to install these dependencies.
Writing R Functions in C++
Rcpp Attributes
Rcpp versions 0.10.1+ include several features that make it very easy to write R functions in C++ and use them seamlessly in interactive R sessions. These features make use of Rcpp attributes, a high-level syntax for adding annotations to C++ source files.
The Rcpp::sourceCpp
function parses a C++ file and looks for functions marked with the Rcpp::export
attribute. A shared library is then built and its exported functions are made available as R functions in the specified environment. For example, this source file contains an implementation of convolve (note the Rcpp::export attribute in the comment above the function):
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector convolveCpp(NumericVector a, NumericVector b) {
int na = a.size(), nb = b.size();
int nab = na + nb - 1;
NumericVector xab(nab);
for (int i = 0; i < na; i++)
for (int j = 0; j < nb; j++)
xab[i + j] += a[i] * b[j];
return xab;
}
The addition of the export attribute allows us to do this from the R prompt:
> sourceCpp("convolve.cpp")
> convolveCpp(x, y)
With Rcpp attributes it's possible to write C++ functions and then source them just as you would an R script. The Rcpp attributes vignette contains more detailed documentation on using attributes.
Using sourceCpp
The RStudio C/C++ editing mode makes the same Source command typically available for R scripts available for C++ source files. You can access this command on the editing toolbar or using the Ctrl+Shift+Enter keyboard shortcut.
The Source command both executes the sourceCpp function and monitors the results of the compilation for errors. If errors do occur then the gcc error log is parsed into a navigable list:
Note that you can also check the Source on Save option to automatically source the C++ file every time it is saved. This variation will keep the keyboard focus within the editor whereas the Source command will move focus to the console.
Embedding R Code
Typically C++ and R code are kept in their own source files. However, it's often convenient to bundle code from both languages into a common source file that can be executed using single call to sourceCpp.
To embed chunks of R code within a C++ source file you include the R code within a block comment that has the prefix of /*** R. Within these R code chunks the RStudio editor automatically switches into R editing mode:
Multiple R code chunks can be included in a C++ file. The sourceCpp function will first compile the C++ code into a shared library and then source all of the embedded R code.
Code Completion
RStudio v0.99 includes comprehensive code completion for C++ based on Clang (the same underlying engine used by XCode and many other C/C++ tools):
Completions are provided for the C++ language, Rcpp, and any other libraries you have imported.
Interactive C++
Rcpp includes some nifty tools to help make working with C++ code just as simple and straightforward as working with R code. You can “source” C++ code into R just like you’d source an R script (no need to deal with Makefiles or build systems). Here’s a Gibbs Sampler implemented with Rcpp:
We can make this function available to R by simply sourcing the C++ file (much like we’d source an R script):
sourceCpp("gibbs.cpp")
gibbs(100, 10)
Thanks to the abstractions provided by Rcpp, the code implementing the Gibbs Sampler in C++ is nearly identical to the code you’d write in R, but runs 20 times faster. RStudio includes full support for Rcpp’s sourceCpp
via the Source button and Ctrl+Shift+Enter keyboard shortcut.
Diagnostics
As you edit C++ source files RStudio uses Clang to scan your code looking for errors, incomplete code, or other conditions worthy of warnings or informational notes. For example:
Diagnostics alert you to the possibility of subtle problems and flag outright incorrect code as early as possible, substantially reducing iteration/debugging time.
Rcpp Package Development
Before developing packages with Rcpp, it's also important to have a firm grounding in the basics of R packages. These basics are covered well by the following articles:
- Writing R Extensions
- R Packages (Hadley Wickham)
- Creating R Packages: A Tutorial (Friedrich Leisch)
- Making an R Package (R.M. Ripley)
- Writing a package that uses Rcpp
Creating a New Package
To create a new Rcpp package use the Create Project command (available on the Projects menu and on the global toolbar) and select the New Directory option. Then select R Package. On the following screen specify the project type as Package w/ Rcpp:
Note that if you have existing R scripts that you'd like to use as the basis for the new package you can specify them here and they'll be included in the new package.
Creating a new project in this fashion will result in a call to the Rcpp.package.skeleton
function to generate the basic scaffolding for the package. If you prefer, you can also call this function directly then follow the instructions below for loading the generated package into RStudio.
Working with an Existing Package
To enable RStudio's package development tools for an existing Rcpp package you should do the following:
- Create a new RStudio Project associated with the package's directory.
- If the package DESCRIPTION file is located either in the project's root directory or at pkg/DESCRIPTION then it will be automatically discovered.
- Alternatively, go to Project Options : Build Tools, select "Package" as the project build tools type, and then specify the the subdirectory containing the package's DESCRIPTION file.
Adding Rcpp to an Existing Package
If you have an existing package which you'd like to add Rcpp to you should consult the Writing a package that uses Rcpp vignette. The most straightforward and reliable approach may be to simply create a new Package w/ Rcpp and then copy the existing packages code and other files into the new package's directory.
Building Packages
Build and Reload
To work with packages in RStudio you use the Build pane, which includes a variety of tools for building and testing packages. While iteratively developing a package in RStudio, you typically use the Build and Reload command to re-build the package and reload it in a fresh R session:
The Build and Reload command performs several steps in sequence to ensure a clean and correct result:
- Calls the
Rcpp::compileAttribures
function to generate code for exported C++ functions - Unloads any existing version of the package (including shared libraries if necessary).
- Builds and installs the package using
R CMD INSTALL
. - Restarts the underlying R session to ensure a clean environment for re-loading the package.
- Reloads the package in the new R session by executing the
library
function.
Note that you can also execute Build and Reload using a keyboard shortcut (Ctrl+Shift+B) as well as configure RStudio to automatically save open source files prior to rebuilding.
Custom options for building and checking packages can be specified using Project Options : Build Tools (see Customizing Package Build Options for more details).
Errors and Warnings
If GCC errors or warnings occur during the build then they are parsed and presented as a navigable list:
RStudio will automatically navigate to the first error in the list (you can subsequently view the other errors by double-clicking them). Note that you can switch between the error list view and the underlying build output using the toggle at the top-right of the Build pane.
Building Multiple Architectures
By default the RStudio Build and Reload command includes the --no-multiarch
option. This makes re-building the package for iterative development and testing much quicker. Note however that when you execute the Build Binary Package command multiple architectures are built by default.
If you prefer to build both architectures during testing and development you can use the Project Options : Build Tools to remove the --no-multiarch
option. Note that when changing architecture configurations you should execute the Clean and Rebuild command to ensure the previous configuration doesn't cause errors in the new build.
Incremental Rebuilds
By default RStudio performs incremental rebuilds of packages. C++ files are only recompiled when they change or any header files change. This provides fast turnaround for incremental development.
If you need to completely rebuild the package you use the Clean and Rebuild command as described above. If you want to always fully rebuild the package you can add the --preclean
option to the Build and Reload command line.
Learning More
Once you've got a basic Rcpp package building within RStudio you'll want to learn about the tools that can be used to test, document, and prepare packages for distribution. Please consult these articles for additional details:
- Building, Testing, and Distributing Packages
- Writing Package Documentation
- Customizing Package Build Options
Using C++11
The default compiler configuration for both Rcpp::sourceCpp and R package development does not support C++11. If you want to enable C++11 for use with Rcpp::sourceCpp you do so by adding the following attribute to your source file:
[[Rcpp::plugins(cpp11)]]
If you want to use C++11 within an R package you need to add the following to the SystemRequirements field of your package DESCRIPTION file:
SystemRequirements: C++11
This requirement is covered in more details in C++11 section of Writing R Extensions.
Comments