Rcpp and Qt Creator

Motivation

  • RStudio is a great IDE for R, but its C++ support is limited
  • Debugging C++ code is difficult with RStudio
  • Qt Ceator is a great IDE for C++ and works very well for debugging

Add the Rtools compiler to Qt Creator (Windows only)

  • be careful not to mix up the 32-bit versions with the 64-bit versions
  • in Tools > Options > Kits in the Compilers tab select a MinGW C++ compiler and Clone it:
compiler1.png

compiler1.png

  • change the name of the cloned compiler to, e.g. Rtools MinGW C++ and change in Compiler path the g++.exe to the g++.exe of your Rtools installation:
compiler2.PNG

compiler2.PNG

  • Just as with the C++ compiler, also clone the MinGW C compiler, rename the cloned compiler and change the Compiler path to the gcc.exe of your Rtools installation
  • Select the Kits tab and clone a default Kit. Clone a 64-bit kit if you want to use a 64-bit compiler or a 32-bit kit to use with a 32-bit compiler. Rename it and select the newly added C and C++ compilers from your Rtools installation:
kit.PNG

kit.PNG

  • Be aware, you cannot use the Qt libraries with the Rtools compiler

Create a C++ Project in Qt Creator

  • New Project > Non-Qt Project > Plain C++ Application proj1.PNG
  • Give the project a meaningful name. I usually use packagename-rcpp-dev and create it in the R-Project’s folder structure: pro2.PNG
  • Windows: choose a Kit with the Rtools compiler & next, next, finish :-) proj3.PNG

Add the Rcpp and RInside libraries

  • in your *.pro file, add:
## Template from the example at http://dirk.eddelbuettel.com/blog/2011/03/25/#rinside_and_qt

## comment this out if you need a different version of R,
## and set set R_HOME accordingly as an environment variable
R_HOME = $$system(R RHOME)

## include headers and libraries for R
RCPPFLAGS =         $$system($$R_HOME/bin/R CMD config --cppflags)
RLDFLAGS =      $$system($$R_HOME/bin/R CMD config --ldflags)
RBLAS =         $$system($$R_HOME/bin/R CMD config BLAS_LIBS)
RLAPACK =       $$system($$R_HOME/bin/R CMD config LAPACK_LIBS)

## if you need to set an rpath to R itself, also uncomment
RRPATH =        -Wl,-rpath,$$R_HOME/lib

## include headers and libraries for Rcpp interface classes
## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted
RCPPINCL =      $$system($$R_HOME/bin/Rscript -e \"Rcpp:::CxxFlags\(\)\")
RCPPLIBS =      $$system($$R_HOME/bin/Rscript -e \"Rcpp:::LdFlags\(\)\")

## include headers and libraries for RInside embedding classes
RINSIDEINCL =       $$system($$R_HOME/bin/Rscript -e \"RInside:::CxxFlags\(\)\")
RINSIDELIBS =       $$system($$R_HOME/bin/Rscript -e \"RInside:::LdFlags\(\)\")

## compiler etc settings used in default make rules
QMAKE_CXXFLAGS +=   $$RCPPWARNING $$RCPPFLAGS $$RCPPINCL $$RINSIDEINCL
QMAKE_LIBS +=           $$RLDFLAGS $$RBLAS $$RLAPACK $$RINSIDELIBS $$RCPPLIBS

Use R, Rcpp and C++ seamlessly

  • Add your Rcpp files just like any other file to your project in Qt Creator, i.e. right-click on the project name in the project structure > Add existing files and add all C++ files you need:

  • you can embed an R session like this:
#include <iostream>
#include <RInside.h>

using namespace std;
using namespace Rcpp;

int main()
{
    RInside R; // this is an R session, yay!
    R.parseEvalQ("i <- 5 + 5"); // parseEvalQ(): do stuff in the R session *Q*uietly
    int x = R["i"];
    cout << "Hello " << x << endl;

    IntegerVector vec = R.parseEval("seq(0, 100, 7)"); // parseEval(): do stuff in R and return the results back to C++

    // Access and output the Rcpp::IntegerVector:
    for (unsigned i = 0; i < vec.size(); i++) {
       cout << vec[i] << " ";
    }
    cout << endl;
    
    // Convert IntegerVector to std::vector (useful for debugging, see explanation below the code)
    vector<int> cpp_vec = as<vector<int> >(vec);

    return 0;
}
  • Debugging works as usual, with the exception, that you can’t see the values that are stored in Rcpp objects. That’s because Rcpp objects are just wrappers to C-pointers (called SEXP) that point to memory locations of R-objects. But fortunately, it is often trivial to convert Rcpp objects to C++ objects:

Random Numbers and seeds

In general, the syncronization of R’s random number generator with Rcpp code works like a charm. But when using this setup with RInside, it often does not work. R’s RNG always returns the first random number without changing the seed, i.e. always the same number. For development and debugging, you’ll need to manually syncronise. Just put

RNGScope scope; // needed for debugging in Qt Creator

in your Rcpp code. You can remove the line once you finished your package and use it in R directly.

Further reading on Rcpp

Rcpp Links