6 ROOT R is an interface in ROOT to call R functions using an R C++ interface (Rcpp, see http://dirk.eddelbuettel.com/code/rcpp.html).
7 This interface opens the possibility in ROOT to use the very large set of mathematical and statistical tools provided by R.
8 With ROOTR you can perform a conversion from ROOT's C++ objects to R's objects, transform the returned R objects into ROOT's C++ objects, then
9 the R functionality can be used directly for statistical studies in ROOT.
12 ROOTR creates a working environment to execute R coding called from `C++`. It allows to translate some datatypes from `C++` to R
13 inside the R environment and vice versa in an easy way to get the most from both R and ROOT.
14 To ease the sending and receiving of data in both environments, I overloaded the operators `<<`,`>>` and `[]`
15 which make look the job as a flow of data between environments, we will see more of that later.
16 With this tool you ca use any library or R package wich allows you to access a big ammount of benefits to make statistical analysis.
17 ROOTR also has a R events processing system, which allows to use the R graphical system from `C++`.
20 To install ROOTR please read first.
22 - [http://root.cern.ch/drupal/content/installing-root-source](http://root.cern.ch/drupal/content/installing-root-source)
23 - [http://root.cern.ch/drupal/content/build-prerequisites](http://root.cern.ch/drupal/content/build-prerequisites)
26 ### COMPILING ROOTR ON MAC WITH CMAKE:
27 **NOTE:** Mac OSX Yosemite last xcode and without macports
33 - [http://xquartz.macosforge.org/](http://xquartz.macosforge.org/)
34 - R last version [http://cran.rstudio.com/bin/macosx/R-3.1.3-mavericks.pkg](http://cran.rstudio.com/bin/macosx/R-3.1.3-mavericks.pkg)
35 - [http://www.cmake.org/files/v3.2/cmake-3.2.1-Darwin-x86_64.dmg](http://www.cmake.org/files/v3.2/cmake-3.2.1-Darwin-x86_64.dmg)
37 To compile with cmake added into ~/.profile
40 export PATH=$PATH:/Applications/CMake.app/Contents/bin/
48 Install needed R packages, open R and in the prompt type
51 install.packages(c('Rcpp','RInside'))
53 select a mirror and install.
55 Download code from git repo
58 git clone -b master-root-R https://github.com/lmoneta/root.git
61 To compile ROOTR lets to create a compilation directory and to activate it use cmake -Dr=ON ..
69 This is a basic video using ROOTR on
71 ](http://www.youtube.com/watch?v=tvhuEen8t7c)
73 ### Compiling ROOTR on Gnu/Linux with CMake:
74 **NOTE:** Tested on Gnu/Linux Debian Jessie with gcc 4.9
78 (For debian-based distros)
81 apt-get install r-base r-base-dev
83 Install needed R packages, open R and in the prompt type
86 install.packages(c('Rcpp','RInside'))
88 select a mirror and install.
89 Download code from git repo
92 git clone -b master-root-R https://github.com/lmoneta/root.git
95 To compile ROOTR lets to create a compilation directory and to activate it use cmake -Dr=ON ..
103 This is a basic video using ROOTR on
105 ](http://www.youtube.com/watch?v=FkrmM2xCPoM)
109 There is a class called TRInterface which is located at the header TRInterface.h and uses the namespace `ROOT::R`, it is in charge
110 of making calls to R to give and obtein data. This class has a series of overcharged operators which ease the passing and obtaining of data
111 and code from R to C++ and vice versa. To create an object of this class the user must use the static methods `ROOT::R::TRInterface::Instance`
112 and `ROOT::R::TRInterface::InstancePtr` which return a reference object and a pointer object respectively.
115 #include<TRInterface.h>
116 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
119 ## Running R code and passing/getting variables.
120 We have different ways to run R code and pass/obtain data to/from R environment: using the methods Execute(code) and
124 #include<TRInterface.h>
126 //creating an instance
127 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
128 //executing simple r commands with the operator <<
129 r<<"print('hello ROOTR')";
130 r<<"vec=c(1,2,3)"<<"print(vec)";
132 //executing R's code using the method Execute that doesn't return anything
133 r.Execute("print('hello ROOTR')");
135 //We execute the code using the method Eval which returns an instance of TRObjectProxy
136 //which can be converted to a ROOTR supported classes
137 std::vector<Int_t> v=r.Eval("c(1,2,3)");
138 std::cout<<v[0]<<" "<<v[1]<<" "<<v[2]<<std::endl;
140 std::vector<Double_t> vd(3);
142 //obtaining variables from R environment using the operators [] and >>
143 r["seq(0,1,0.5)"]>>vd;
144 std::cout<<vd[0]<<" "<<vd[1]<<" "<<vd[2]<<std::endl;
146 std::vector<Int_t> v1(3);
156 //Creating a matrix inside r environment and converting it into a TMatrixD
157 r<<"mat<-matrix(c(0.1,0.2,0.3,0.4),nrow=2)";
161 So, working with ROOTR is like working with flows of data to pass, obtain and process data.
163 ## Passing functions from ROOT to R
164 You can pass functions from ROOT to R using the opetrators `<<` and `=` or using the class TRFunction, but the arguments and datatypes of the return value cannot be pointers. They must be ROOTR supported datatypes.
165 So instead of using `*Double_t` you must use `std::vector` and instead of `*Char_t` use TString or `std::string`.
167 For this example we need to create a macro, so save it as fun.C
170 #include<TRInterface.h>
173 Double_t myfun(Double_t x)
178 Double_t myfun2(std::vector<Double_t> x) //use std::vector<Double_t> instead Double_t*
180 return x[1]*cos(x[0]);
185 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
186 r["dilog"]<<ROOT::R::TRFunctionExport(TMath::DiLog);
189 r<<"print(dilog(0))";
190 r<<"print(myfun(0))";
191 r<<"print(myfun2(c(0,4)))";
196 - For overloaded functions you should pass the function with a explicit cast to the wanted function.
197 - The system works with templates and the template can not resolve the correct type of function because it is overloaded.
198 - If you pass a function without the explicit cast you will get a very ugly traceback.
199 - A lot of common standard functions for example from math.h like sin, cos etc.. are overloaded, take care passing it.
202 #include<TRInterface.h>
204 Double_t myfun(Double_t x)
216 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
217 r["myfund"]<<(Double_t (*)(Double_t))myfun;
218 r["myfuni"]<<(Int_t (*)(Int_t))myfun;
220 r<<"print(myfund(0.0))";
221 r<<"print(myfuni(1))";
226 You can wrap a class and expose it in R environment using only a pair of macrodefinitions and the template class
228 The `ROOTR_EXPOSED_CLASS(Class)` macro allows you to expose the class as a new datatype of R, but it has to be alongside
229 the `ROOTR_MODULE(Module)` macro which allows you to create an internal R module and make the class wrapping
230 To do this you must use inside the `ROOTR_MODULE` braces the class `ROOT::R::class_<>` and specify
231 each constructor, attribute or method that the class to export has.
232 Then the macrodefinition `LOAD_ROOTR_MODULE(Module)` can load the module and the class in R's environment.
233 You can find a more clear instruction by looking at a example below in Functor section.
236 DataFrame? is a very important datatype in R and in ROOTR we have a class to manipulate
237 dataframes called TRDataFrame, with a lot of very useful operators overloaded to work with TRDataFrame's objects
238 in a similar way that in the R environment but from c++ in ROOT.
241 Lets to create need data to play with dataframe features
244 ////////////////////////
245 //creating variables//
246 ////////////////////////
248 std::vector<Double_t> v2(3);
249 std::array<Int_t,3> v3{ {1,2,3} };
250 std::list<std::string> names;
252 //////////////////////
254 //////////////////////
263 names.push_back("v1");
264 names.push_back("v2");
265 names.push_back("v3");
267 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
269 In R the dataframe have associate to every column a label, in ROOTR you can have the same label using the class ROOT::R::Label to create a TRDataFrame where you data
270 have a label associate.
273 /////////////////////////////////////////////////
274 //creating dataframe object with its labels//
275 /////////////////////////////////////////////////
277 ROOT::R::TRDataFrame df1(ROOT::R::Label["var1"]=v1,ROOT::R::Label["var2"]=v2,ROOT::R::Label["var3"]=v3,ROOT::R::Label["strings"]=names);
279 //////////////////////////////////////////////
280 //Passing dataframe to R's environment//
281 //////////////////////////////////////////////
289 var1 var2 var3 strings
294 Manipulating data between dataframes
297 ////////////////////////////////
298 //Adding colunms to dataframe //
299 ////////////////////////////////
302 //filling the vector fro R's environment
303 r["c(-1,-2,-3)"]>>v4;
304 //adding new colunm to df1 with name var4
306 //updating df1 in R's environment
314 var1 var2 var3 strings var4
320 Getting data frames from R's environment
323 //////////////////////////////////////////
324 //Getting dataframe from R's environment//
325 //////////////////////////////////////////
326 ROOT::R::TRDataFrame df2;
328 r<<"df2<-data.frame(v1=c(0.1,0.2,0.3),v2=c(3,2,1))";
342 Vector (3) is as follows
350 Vector (3) is as follows
360 ///////////////////////////////////////////
361 //Working with colunms between dataframes//
362 ///////////////////////////////////////////
364 df2["v3"]<<df1["strings"];
366 //updating df2 in R's environment
380 ///////////////////////////////////////////
381 //Working with colunms between dataframes//
382 ///////////////////////////////////////////
384 //passing values from colunm v3 of df2 to var1 of df1
385 df2["v3"]>>df1["var1"];
386 //updating df1 in R's environment
394 var1 var2 var3 strings var4
400 ## Plotting with R's graphical system.
401 ROOTR supports an eventloop for R's graphical system which allows plotting using the R functions to the
402 graphical system or generating images(ps, pdf png, etc).
403 You can find a demo in Interpolation below in examples section.
406 The interactive mode lets you get the R's command line within ROOT's command line to run R code with tab completion support.
407 The variables created in the interactive mode can be passed to ROOT with TRObjectProxy and the method ParseEval?.
408 To initialize the interactive mode just call Interactive() method and type ".q" to exit from R's prompt and to go to the ROOT's prompt again.
411 [omazapa] [tuxhome] [~]$ root -l
412 root [0] #include<TRInterface.h>
413 root [1] ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
414 root [2] r.Interactive()
416 seq seq_along seq.Date seq.default seq.int seq_len seq.POSIXt sequence
419 root [3] TVectorD v=r.ParseEval("a");
422 Vector (9) is as follows
440 The examples can also be found in `$ROOTSYS/tutorials/r`
442 ## Creating a Functor
443 A functor is a class which wraps a function, very useful when states and propierties
444 associated to that function are needed.
445 In this example I show how to give support to a custom class to be used in R's environment,
446 which at the same time is a functor.
449 #include<TRInterface.h>
452 typedef Double_t (*Function)(Double_t);
454 //Functor class with the function inside
461 void setFunction(Function fun)
466 Bool_t getStatus(){return status;}
467 Double_t doEval(Double_t x) {
474 //this macro exposes the class into R's enviornment
475 // and lets you pass objects directly.
476 ROOTR_EXPOSED_CLASS(MyFunctor)
478 //Macro to create a module
479 ROOTR_MODULE(MyFunctorModule) {
480 ROOT::R::class_<MyFunctor>( "MyFunctor" )
481 //creating a default constructor
483 //adding the method doEval to evaluate the internal function
484 .method( "doEval", &MyFunctor::doEval )
485 .method( "getStatus", &MyFunctor::getStatus)
491 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
492 ////////////////////////////////////////////////////////////
493 //Creating a functor with default function TMath::BesselY1//
494 // and status false from R's environment //
495 ////////////////////////////////////////////////////////////
496 //Loading module into R's enviornment
497 r["MyFunctorModule"]<<LOAD_ROOTR_MODULE(MyFunctorModule);
499 //creating a class variable from the module
500 r<<"MyFunctor <- MyFunctorModule$MyFunctor";
501 //creating a MyFunctor's object
502 r<<"u <- new(MyFunctor)";
505 r<<"print(u$getStatus())";
507 //printing values from Functor and Function
508 r<<"print(sprintf('value in R = %f',u$doEval( 1 )))";
509 std::cout<<"value in ROOT = "<<TMath::BesselY1(1)<<std::endl;
511 ////////////////////////////////////////////////////////////
512 //creating a MyFunctor's object and passing object to R's //
513 //enviornment, the status should be true because is not //
514 //using the default function //
515 ////////////////////////////////////////////////////////////
517 functor.setFunction(TMath::Erf);
518 r["functor"]<<functor;
519 //printing the status that should be true
520 r<<"print(functor$getStatus())";
521 r<<"print(sprintf('value in R = %f',functor$doEval( 1 )))";
522 std::cout<<"value in ROOT = "<<TMath::Erf(1)<<std::endl;
526 ## Simple fitting in R and plot in ROOT
527 The next example creates an exponential fit.
528 The idea is to create a set of numbers x,y with noise from ROOT,
529 pass them to R and fit the data to `x^3`,
530 get the fitted coefficient(power) and plot the data,
531 the known function and the fitted function using ROOT's classes.
534 #include<TRInterface.h>
537 TCanvas *SimpleFitting(){
538 TCanvas *c1 = new TCanvas("c1","Curve Fitting",700,500);
541 // draw a frame to define the range
542 TMultiGraph *mg = new TMultiGraph();
544 // create the first graph (points with gaussian noise)
548 //Generate the points along a X^3 with noise
551 for (Int_t i = 0; i < n; i++) {
552 x1[i] = rg.Uniform(0, 1);
553 y1[i] = TMath::Power(x1[i], 3) + rg.Gaus() * 0.06;
556 TGraph *gr1 = new TGraph(n,x1,y1);
557 gr1->SetMarkerColor(kBlue);
558 gr1->SetMarkerStyle(8);
559 gr1->SetMarkerSize(1);
562 // create the second graph
563 TF1 *f_known=new TF1("f_known","pow(x,3)",0,1);
564 TGraph *gr2 = new TGraph(f_known);
565 gr2->SetMarkerColor(kRed);
566 gr2->SetMarkerStyle(8);
567 gr2->SetMarkerSize(1);
569 //passing data to Rfot fitting
570 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
571 r["x"]<<TVectorD(n, x1);
572 r["y"]<<TVectorD(n, y1);
573 //creating a R data frame
574 r<<"ds<-data.frame(x=x,y=y)";
575 //fitting x and y to X^power using Nonlinear Least Squares
576 r<<"m <- nls(y ~ I(x^power),data = ds, start = list(power = 1),trace = T)";
577 //getting the exponent
579 r["summary(m)$coefficients[1]"]>>power;
581 TF1 *f_fitted=new TF1("f_fitted","pow(x,[0])",0,1);
582 f_fitted->SetParameter(0,power);
583 //plotting the fitted function
584 TGraph *gr3 = new TGraph(f_fitted);
585 gr3->SetMarkerColor(kGreen);
586 gr3->SetMarkerStyle(8);
587 gr3->SetMarkerSize(1);
592 //displaying basic results
593 TPaveText *pt = new TPaveText(0.1,0.6,0.5,0.9,"brNDC");
594 pt->SetFillColor(18);
595 pt->SetTextAlign(12);
596 pt->AddText("Fitting x^power ");
597 pt->AddText(" \"Blue\" Points with gaussian noise to be fitted");
598 pt->AddText(" \"Red\" Known function x^3");
600 fmsg.Form(" \"Green\" Fitted function with power=%.4lf",power);
607 In the first image you can see the blue dots wichi are the function `x^3` with gaussian noise, the red dots correspond to
608 the original function and the green ones correspond to the fitted function.
609 
611 ## Global Minimization in R using the package DEoptim
612 DEoptim is a R package for Differential Evolution Minimization that lets you do global
614 To install this package you just need to run:
617 #include<TRInterface.h>
618 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
619 r<<"install.packages('DEoptim',repos='http://cran.rstudio.com/')";
622 Then create a macro named GlobalMinimization.C with the next code.
625 #include<TRInterface.h>
626 #include<TBenchmark.h>
629 //In the next function the *double pointer should be changed by a TVectorD datatype,
630 //because the pointer has no meaning in the R enviroment.
631 //This is a generalization of the RosenBrock function, with the min xi=1 and i>0.
632 Double_t GenRosenBrock(const TVectorD xx )
634 int length=xx.GetNoElements();
637 for(int i=0;i<(length-1);i++)
639 result+=pow(1-xx[i],2)+100*pow(xx[i+1]-pow(xx[i],2),2);
645 Double_t Rastrigin(const TVectorD xx)
647 int length=xx.GetNoElements();
648 Double_t result=10*length;
649 for(int i=0;i<length;i++)
651 result+=xx[i]*xx[i]-10*cos(6.2831853*xx[i]);
656 void GlobalMinimization()
659 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
661 Bool_t installed=r.Eval("is.element('DEoptim', installed.packages()[,1])");
664 std::cout<<"Package DEoptim no installed in R"<<std::endl;
665 std::cout<<"Run install.packages('DEoptim') in R's environment"<<std::endl;
670 r<<"suppressMessages(library(DEoptim, quietly = TRUE))";
672 // passing RosenBrock function to R
673 r["GenRosenBrock"]<<GenRosenBrock;
675 //maximun number of iterations
677 //n = size of vector that is an argument for GenRosenBrock
680 r<<"ll<-rep(-25, n)";
684 bench.Start("GlobalMinimizationRosenBrock");
685 //calling minimization and timing it.
686 r<<"result1<-DEoptim(fn=GenRosenBrock,lower=ll,upper=ul,control=list(NP=10*n,itermax=MaxIter,trace=FALSE))";
687 std::cout<<"-----------------------------------------"<<std::endl;
688 std::cout<<"RosenBrock's minimum in: "<<std::endl;
689 r<<"print(result1$optim$bestmem)";
690 std::cout<<"Bechmark Times"<<std::endl;
692 bench.Show("GlobalMinimizationRosenBrock");
695 //passing RosenBrock function to R
696 r["Rastrigin"]<<Rastrigin;
697 //maximun number of iterations
699 //n = size of a vector which is an argument for Rastrigin
706 bench.Start("GlobalMinimizationRastrigin");
707 //calling minimization and timing it.
708 r<<"result2<-DEoptim(fn=Rastrigin,lower=ll,upper=ul,control=list(NP=10*n,itermax=MaxIter,trace=FALSE))";
709 std::cout<<"-----------------------------------------"<<std::endl;
710 std::cout<<"Rastrigin's minimum in: "<<std::endl;
711 r<<"print(result2$optim$bestmem)";
712 std::cout<<"Bechmark Times"<<std::endl;
714 bench.Show("GlobalMinimizationRastrigin");
715 r<<"dev.new(title='RosenBrock Convergence')";
716 r<<"plot(result1,type='o',pch='.')";
717 r<<"dev.new(title='Rastrigin Convergence')";
718 r<<"plot(result2,type='o',pch='.')";
721 In the image you can see the convergence plots of the functions and their minimum.
722 For RosenBrock is (1,1,1) and for Rastrigin is (0,0,0).
723 
725 ## Interpolation (Plotting in R)
726 This example shows an interpolation using the function aproxfun and how to make a plot with R's
729 More Information on R interpolation at
730 [http://stat.ethz.ch/R-manual/R-patched/library/stats/html/approxfun.html](http://stat.ethz.ch/R-manual/R-patched/library/stats/html/approxfun.html)
733 #include<TRInterface.h>
739 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
742 std::vector<Double_t> x(10),y(10);
743 for(int i=0;i<10;i++)
753 r<<"dev.new()";//Required to activate new window for plotting
754 //Plot parameter. Plotting using two rows and one column
755 r<<"par(mfrow = c(2,1))";
757 //plotting the points
758 r<<"plot(x, y, main = 'approx(.) and approxfun(.)')";
760 //The function "approx" returns a list with components x and y,
761 //containing n coordinates which interpolate the given data points according to the method (and rule) desired.
762 r<<"points(approx(x, y), col = 2, pch = '*')";
763 r<<"points(approx(x, y, method = 'constant'), col = 4, pch = '*')";
766 //The function "approxfun" returns a function performing (linear or constant)
767 //interpolation of the given data.
768 //For a given set of x values, this function will return the corresponding interpolated values.
769 r<<"f <- approxfun(x, y)";
771 r<<"curve(f(x), 0, 11, col = 'green2')";
775 //using approxfun with const method
776 r<<"fc <- approxfun(x, y, method = 'const')";
777 r<<"curve(fc(x), 0, 10, col = 'darkblue', add = TRUE)";
778 // different interpolation on left and right side :
779 r<<"plot(approxfun(x, y, rule = 2:1), 0, 11,col = 'tomato', add = TRUE, lty = 3, lwd = 2)";
782 The image shows the interpolated function plotted within R
783 
785 ## Integration (Passing vectorized function to R)
786 Numerical integration using R passing the function from ROOT
790 #include<TRInterface.h>
791 #include<Math/Integrator.h>
794 //To integrate using R the function must be vectorized
795 //The idea is just to receive a vector like an argument,to evaluate
796 //every element saving the result in another vector
797 //and return the resultant vector.
798 std::vector<Double_t> BreitWignerVectorized(std::vector<Double_t> xx)
800 std::vector<Double_t> result(xx.size());
801 for(Int_t i=0;i<xx.size();i++)
803 result[i]=TMath::BreitWigner(xx[i]);
808 double BreitWignerWrap( double x){
809 return TMath::BreitWigner(x);
816 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
818 r["BreitWigner"]=BreitWignerVectorized;
820 Double_t value=r.Eval("integrate(BreitWigner, lower = -2, upper = 2)$value");
822 std::cout.precision(18);
823 std::cout<<"Integral of the BreitWigner Function in the interval [-2, 2] R = "<<value<<std::endl;
826 ROOT::Math::WrappedFunction<> wf(BreitWignerWrap);
827 ROOT::Math::Integrator i(wf);
828 value=i.Integral(-2,2);
829 std::cout<<"Integral of the BreitWigner Function in the interval [-2, 2] MathMore = "<<value<<std::endl;
832 TF1 f1("BreitWigner","BreitWignerWrap(x)");
833 value=f1.Integral(-2,2);
834 std::cout<<"Integral of the BreitWigner Function in the interval [-2, 2] TF1 = "<<value<<std::endl;
837 value=r.Eval("integrate(BreitWigner, lower = -Inf, upper = Inf)$value");
838 std::cout<<"Integral of BreitWigner Function in the interval [-Inf, Inf] R = "<<value<<std::endl;
844 - http://oproject.org/tiki-index.php?page=ROOT+R+Users+Guide
845 - https://root.cern.ch/drupal/content/how-use-r-root-root-r-interface