RSS‎ > ‎

Linking Xcode, C++ and R to create plots

posted May 26, 2015, 7:03 PM by Brian Hall   [ updated May 26, 2015, 7:48 PM ]
Great for Mac/Xcode users who love the computational speed of C++, but also need nice visualizations!

I like C++ and my text mining app is written in C++. The reasons: speed (e.g., file I/O, data structures) and STL. However, one major weakness of C++ is visualization, something R is quite good at if you can figure out all the syntax quirks. So I set out to combine the two in my app for visualization purposes using some prevalent and well-respected packages. Xcode is my chosen IDE. The process was setup-heavy, and took some time digging here and there. I documented the process so that anyone else looking to do the same might find this post helpful. I have also provided a working code example.

- Works on Mavericks (10.9), yet to be tested on Yosemite (10.10)...
- Xcode 6.1.1
- If not installed, install XQuartz (http://xquartz.macosforge.org/landing/)
- If not installed, install R (3.2 or later) (http://www.r-project.org)
- Install ggplot2 (this will download a dozen or so packages, all of which need installed)
   You could forego installing ggplot2 and use R's plot() function, but ggplot2 has better aesthetics.
   To install R packages, inside R run:  install.packages("package_name")
   Then in Terminal run:  R CMD INSTALL /path_to_package.tgz

- Add necessary R header files to the Xcode project's header files search path list.
   Project->Build Settings->Search Paths->Header Search Paths
   I recommend using the aliased location:   /Library/Frameworks/R.framework/Headers/
  Or you could go for the literal location such as:
 /Library/Frameworks/R.framework/Versions/3.2/Resources/include/
  Alternatively you could copy all of the R header files into your default /include directory.

- Add the R and RInside dynamic libraries to your Xcode project.
  Rcpp does not require a dynamic library.
  I recommend creating a group in your project called dylibs to place any dynamic libraries you may
  need for your project.
  Add the R dynamic library:
  /Library/Frameworks/R.framework/Resources/lib/libR.dylib
  Add the RInside dynamic library:
  /Library/Frameworks/R.framework/Versions/Current(or 3.2)/
  Resources/library/RInside/lib/libRInside.dylib

- Test it out. Here is a code example (creates myPlot.png on desktop):

#include  <RInside.h>                   // for the embedded R via RInside

int main(int argc, char *argv[]) {
   
   // create an embedded R instance
   RInside R(argc, argv);
   
   // demonstrates setting R variables to C++ variables
   std::string outPath = "~/Desktop";
   std::string outFile = "myPlot.png";
   R["outPath"] = outPath;
   R["outFile"] = outFile;
   
   // build the sequence of R commands as a string
   std::string cmd = "library(ggplot2); "
   "df <- data.frame(column1 = seq(1:10), column2 = seq(1:10)); "
   "myPlot <- ggplot(data=df, aes(x=column1, y=column2, group=1))
    +geom_line()+ylim(0,10); "
   "print(myPlot); "
   "ggsave(filename=outFile, path=outPath, plot=myPlot); "
   ;
   
// run parseEval, passing the R cmd R.parseEval(cmd); std::cin.get(); return 0; }
Due to the cin.get(), the Quartz window will be accessible, but will "pinwheel" until you hit return in the app window.