Creating an R Package with Native Code using Rcpp.
There does not appear to be a good set of instructions on getting a new custom R Package (utilizing Rcpp to call C++ from R) so given that I have gone through the pain of configuring this for a project I am working on I decided to write down some instructions on what I did.
Initial Set-up
I have the following pieces of software installed.
- R Studio – 0.99.902
- R Version – 3.3.0
- R Tools – 3.3.0.1959
As getting R and R Studio installed and configured are already covered by a number posts I won’t repeat those steps here (just make sure that you install R before you install R Studio).
From within R Studio install the devtools package.
From the console you can use the following command
install.packages(“devtools”)
Next install the Rcpp package
From the console you can use the following command:
install.packages(“Rcpp”)
Next create the package that will contain our native library and the R code to call the library.
Creating and build the package.
To create the package from R Studio menu New -> New Project
For this project I am going to use a new directory so select that option in the dialog.
Select R Package for the project type (this will generate the skeleton R Package project for you).
Set the package name and then provide a location where the sub directories will be created. For my example my package will be called testprojone and I am created this package in the directory “D:/AllData”
RStudio will generate a number of files and directories under “D:\AllData\testprojone”.
Now we have the package we can test that this works by calling the hello function (which is automatically created), but first we need to build and register the package.
From the RStudio use the following command
Build -> Build and Reload (Ctrl +Shift +B)
In the Build output you should see the following output
==> Rcmd.exe INSTALL –no-multiarch –with-keep.source testprojone
* installing to library ‘D:/Program Files/R/R-3.3.0/library’
* installing *source* package ‘testprojone’ …
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (testprojone)
In the console the package should be (re)loaded.
library(testprojone)
Now with the package loaded we can run the hello function to make sure that everything is working.
>hello()
[1] “Hello, world!”
Create and compiling the C++ code.
Congratulations your package is loading however we want to implement our code in C++ rather than R itself so lets add a new C++ file.
File -> New File -> C++
As this point you may be prompted to install/load additional tools into R Studio, in which case select the Yes option.
By default the file contains a test function called timesTwo with the following code.
// [[Rcpp::export]]
NumericVector timesTwo(NumericVector x)
{ return x * 2;}
Before we rebuild our package we first save the new C++ file.
Create a new directory called “src” under the package root directory and save the untitled file as SimpleExample.cpp under the “src” directory.
The package structure should now appear as follows.
Open the DESCRIPTION file (in the root of the package) and add the following two lines.
LinkingTo: Rcpp
Imports: Rcpp
The contents of the file should now look like this.
Package: testprojone
Type: Package
Title: What the Package Does (Title Case)
Version: 0.1.0
Author: Who wrote it
Maintainer: Who to complain to <yourfault@somewhere.net>
Description: More about what it does (maybe more than one line)
License: What license is it under?
LazyData: TRUE
LinkingTo: Rcpp
Imports: Rcpp
As this is an example I am going to leave the default values for the rest of the parameters in this file.
When you recompile you should see a testprojone.dll generated with the same name as the package. This contains the compiled C++ function from the SimpleExample.cpp file we saved earlier.
Now include information for this dll in the NAMESPACE file (in the root of the package) by adding the following lines.
useDynLib(“testprojone”)
importFrom(Rcpp, sourceCpp)
The contents of the file should now look like this:
useDynLib(“testprojone”)
importFrom(Rcpp, sourceCpp)
exportPattern(“^[[:alpha:]]+”)
When you “Build and Reload” you should see 2 new files generated RcppExports.cpp created under the /src directory and RcppExports.R under the /R directory, if you don’t see these files look in the “Build” window for any errors. If you edit either of these files manually the next time you rebuild your changes will be replaced.
RcppExports.cpp contains the functions that are used by the R code to map to the C++ function.
// timesTwo
NumericVector timesTwo(NumericVector x);
RcppExport SEXP testprojone_timesTwo(SEXP xSEXP) {
BEGIN_RCPP
Rcpp::RObject __result;
Rcpp::RNGScope __rngScope;
Rcpp::traits::input_parameter< NumericVector >::type x(xSEXP);
__result = Rcpp::wrap(timesTwo(x));
return __result;
END_RCPP
}
RcppExports.R contains the R function to call the C++ function using the “Call” function specifying the function to call, the package containing the function and any parameters passed.
timesTwo <- function(x) {
.Call('testprojone_timesTwo', PACKAGE = 'testprojone', x)
}
If everything is configured correctly from the R Console window you should be able to run the timesTwo function.
> library(testprojone)
> timesTwo(100)
[1] 200
Troubleshooting
If you installed Rtools in a different directory other than C:\Rtools then in the “Build” window when R Studio compiles the C++ code you will get an error that directory “C:\Rtools” cannot be found, in which case set the following environment variable (with your path to Rtools) from the Rstudio Console using the following command
Sys.setenv(BINPREF = “D:/Rtools/mingw_64/bin/”)
Then “Build and Reload” the package.