4 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).
5 This interface opens the possibility in ROOT to use the very large set of mathematical and statistical tools provided by R.
6 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
7 the R functionality can be used directly for statistical studies in ROOT.
10 ROOTR creates a working environment to execute R coding called from `C++`. It allows to translate some datatypes from `C++` to R
11 inside the R environment and vice versa in an easy way to get the most from both R and ROOT.
12 To ease the sending and receiving of data in both environments, I overloaded the operators `<<`,`>>` and `[]`
13 which make look the job as a flow of data between environments, we will see more of that later.
14 With this tool you ca use any library or R package wich allows you to access a big amount of benefits to make statistical analysis.
15 ROOTR also has a R events processing system, which allows to use the R graphical system from `C++`.
18 To install ROOTR please read first.
20 - [https://root.cern.ch/building-root](https://root.cern.ch/building-root)
21 - [https://root.cern.ch/build-prerequisites](https://root.cern.ch/build-prerequisites)
24 ### COMPILING ROOTR ON MAC WITH CMAKE:
25 **NOTE:** Mac OSX Yosemite last xcode and without macports
31 - [xquartz](http://xquartz.macosforge.org/)
32 - [R last version](https://www.r-project.org)
33 - [cmake](https://cmake.org/download/)
35 To compile with cmake added into ~/.profile
38 export PATH=$PATH:/Applications/CMake.app/Contents/bin/
46 Install needed R packages, open R and in the prompt type
49 install.packages(c('Rcpp','RInside'))
51 select a mirror and install.
53 Install the next additional packages for R TMVA interface
56 install.packages(c('C50','RSNNS','e1071','xgboost'))
60 Download code from git repo
63 git clone http://root.cern.ch/git/root.git
66 To compile ROOTR lets to create a compilation directory and to activate it use cmake -Dr=ON ..
75 ### Compiling ROOTR on Gnu/Linux with CMake:
76 **NOTE:** Tested on Gnu/Linux Debian Jessie with gcc 4.9
80 (For debian-based distros)
83 apt-get install r-base r-base-dev
85 Install needed R packages, open R and in the prompt type
88 install.packages(c('Rcpp','RInside'))
90 select a mirror and install.
92 Install the next additional packages for R TMVA interface
95 install.packages(c('C50','RSNNS','e1071','xgboost'))
98 Download code from git repo
101 git clone http://root.cern.ch/git/root.git
104 To compile ROOTR lets to create a compilation directory and to activate it use cmake -Dr=ON ..
113 ## How does it work ?
114 There is a class called TRInterface which is located at the header TRInterface.h and uses the namespace `ROOT::R`, it is in charge
115 of making calls to R to give and obtain data. This class has a series of overcharged operators which ease the passing and obtaining of data
116 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`
117 and `ROOT::R::TRInterface::InstancePtr` which return a reference object and a pointer object respectively.
120 #include<TRInterface.h>
121 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
124 ## Running R code and passing/getting variables.
125 We have different ways to run R code and pass/obtain data to/from R environment: using the methods Execute(code) and
129 #include<TRInterface.h>
131 //creating an instance
132 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
133 //executing simple r commands with the operator <<
134 r<<"print('hello ROOTR')";
135 r<<"vec=c(1,2,3)"<<"print(vec)";
137 //executing R's code using the method Execute that doesn't return anything
138 r.Execute("print('hello ROOTR')");
140 //We execute the code using the method Eval which returns an instance of TRObjectProxy
141 //which can be converted to a ROOTR supported classes
142 std::vector<Int_t> v=r.Eval("c(1,2,3)");
143 std::cout<<v[0]<<" "<<v[1]<<" "<<v[2]<<std::endl;
145 std::vector<Double_t> vd(3);
147 //obtaining variables from R environment using the operators [] and >>
148 r["seq(0,1,0.5)"]>>vd;
149 std::cout<<vd[0]<<" "<<vd[1]<<" "<<vd[2]<<std::endl;
151 std::vector<Int_t> v1(3);
161 //Creating a matrix inside r environment and converting it into a TMatrixD
162 r<<"mat<-matrix(c(0.1,0.2,0.3,0.4),nrow=2)";
166 So, working with ROOTR is like working with flows of data to pass, obtain and process data.
168 ## Passing functions from ROOT to R
169 You can pass functions from ROOT to R using the operators `<<` and `=` or using the class TRFunction, but the arguments and datatypes of the return value cannot be pointers. They must be ROOTR supported datatypes.
170 So instead of using `*Double_t` you must use `std::vector` and instead of `*Char_t` use TString or `std::string`.
172 For this example we need to create a macro, so save it as fun.C
175 #include<TRInterface.h>
178 Double_t myfun(Double_t x)
183 Double_t myfun2(std::vector<Double_t> x) //use std::vector<Double_t> instead Double_t*
185 return x[1]*cos(x[0]);
190 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
191 r["dilog"]<<ROOT::R::TRFunctionExport(TMath::DiLog);
194 r<<"print(dilog(0))";
195 r<<"print(myfun(0))";
196 r<<"print(myfun2(c(0,4)))";
201 - For overloaded functions you should pass the function with a explicit cast to the wanted function.
202 - The system works with templates and the template can not resolve the correct type of function because it is overloaded.
203 - If you pass a function without the explicit cast you will get a very ugly traceback.
204 - A lot of common standard functions for example from math.h like sin, cos etc.. are overloaded, take care passing it.
207 #include<TRInterface.h>
209 Double_t myfun(Double_t x)
221 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
222 r["myfund"]<<(Double_t (*)(Double_t))myfun;
223 r["myfuni"]<<(Int_t (*)(Int_t))myfun;
225 r<<"print(myfund(0.0))";
226 r<<"print(myfuni(1))";
231 You can wrap a class and expose it in R environment using only a pair of macrodefinitions and the template class
233 The `ROOTR_EXPOSED_CLASS(Class)` macro allows you to expose the class as a new datatype of R, but it has to be alongside
234 the `ROOTR_MODULE(Module)` macro which allows you to create an internal R module and make the class wrapping
235 To do this you must use inside the `ROOTR_MODULE` braces the class `ROOT::R::class_<>` and specify
236 each constructor, attribute or method that the class to export has.
237 Then the macrodefinition `LOAD_ROOTR_MODULE(Module)` can load the module and the class in R's environment.
238 You can find a more clear instruction by looking at a example below in Functor section.
241 DataFrame? is a very important datatype in R and in ROOTR we have a class to manipulate
242 dataframes called TRDataFrame, with a lot of very useful operators overloaded to work with TRDataFrame's objects
243 in a similar way that in the R environment but from c++ in ROOT.
246 Lets to create need data to play with dataframe features
249 ////////////////////////
250 //creating variables//
251 ////////////////////////
253 std::vector<Double_t> v2(3);
254 std::array<Int_t,3> v3{ {1,2,3} };
255 std::list<std::string> names;
257 //////////////////////
259 //////////////////////
268 names.push_back("v1");
269 names.push_back("v2");
270 names.push_back("v3");
272 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
274 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
275 have a label associate.
278 /////////////////////////////////////////////////
279 //creating dataframe object with its labels//
280 /////////////////////////////////////////////////
282 ROOT::R::TRDataFrame df1(ROOT::R::Label["var1"]=v1,ROOT::R::Label["var2"]=v2,ROOT::R::Label["var3"]=v3,ROOT::R::Label["strings"]=names);
284 //////////////////////////////////////////////
285 //Passing dataframe to R's environment//
286 //////////////////////////////////////////////
294 var1 var2 var3 strings
299 Manipulating data between dataframes
302 ////////////////////////////////
303 //Adding columns to dataframe //
304 ////////////////////////////////
307 //filling the vector fro R's environment
308 r["c(-1,-2,-3)"]>>v4;
309 //adding new column to df1 with name var4
311 //updating df1 in R's environment
319 var1 var2 var3 strings var4
325 Getting data frames from R's environment
328 //////////////////////////////////////////
329 //Getting dataframe from R's environment//
330 //////////////////////////////////////////
331 ROOT::R::TRDataFrame df2;
333 r<<"df2<-data.frame(v1=c(0.1,0.2,0.3),v2=c(3,2,1))";
347 Vector (3) is as follows
355 Vector (3) is as follows
365 ///////////////////////////////////////////
366 //Working with columns between dataframes//
367 ///////////////////////////////////////////
369 df2["v3"]<<df1["strings"];
371 //updating df2 in R's environment
385 ///////////////////////////////////////////
386 //Working with columns between dataframes//
387 ///////////////////////////////////////////
389 //passing values from column v3 of df2 to var1 of df1
390 df2["v3"]>>df1["var1"];
391 //updating df1 in R's environment
399 var1 var2 var3 strings var4
405 ## Plotting with R's graphical system.
406 ROOTR supports an eventloop for R's graphical system which allows plotting using the R functions to the
407 graphical system or generating images(ps, pdf png, etc).
408 You can find a demo in Interpolation below in examples section.
411 The interactive mode lets you get the R's command line within ROOT's command line to run R code with tab completion support.
412 The variables created in the interactive mode can be passed to ROOT with TRObjectProxy and the method ParseEval?.
413 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.
416 [omazapa] [tuxhome] [~]$ root -l
417 root [0] #include<TRInterface.h>
418 root [1] ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
419 root [2] r.Interactive()
421 seq seq_along seq.Date seq.default seq.int seq_len seq.POSIXt sequence
424 root [3] TVectorD v=r.ParseEval("a");
427 Vector (9) is as follows
445 The examples can also be found in `$ROOTSYS/tutorials/r`
447 ## Creating a Functor
448 A functor is a class which wraps a function, very useful when states and properties
449 associated to that function are needed.
450 In this example I show how to give support to a custom class to be used in R's environment,
451 which at the same time is a functor.
454 #include<TRInterface.h>
457 typedef Double_t (*Function)(Double_t);
459 //Functor class with the function inside
466 void setFunction(Function fun)
471 Bool_t getStatus(){return status;}
472 Double_t doEval(Double_t x) {
479 //this macro exposes the class into R's environment
480 // and lets you pass objects directly.
481 ROOTR_EXPOSED_CLASS(MyFunctor)
483 //Macro to create a module
484 ROOTR_MODULE(MyFunctorModule) {
485 ROOT::R::class_<MyFunctor>( "MyFunctor" )
486 //creating a default constructor
488 //adding the method doEval to evaluate the internal function
489 .method( "doEval", &MyFunctor::doEval )
490 .method( "getStatus", &MyFunctor::getStatus)
496 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
497 ////////////////////////////////////////////////////////////
498 //Creating a functor with default function TMath::BesselY1//
499 // and status false from R's environment //
500 ////////////////////////////////////////////////////////////
501 //Loading module into R's environment
502 r["MyFunctorModule"]<<LOAD_ROOTR_MODULE(MyFunctorModule);
504 //creating a class variable from the module
505 r<<"MyFunctor <- MyFunctorModule$MyFunctor";
506 //creating a MyFunctor's object
507 r<<"u <- new(MyFunctor)";
510 r<<"print(u$getStatus())";
512 //printing values from Functor and Function
513 r<<"print(sprintf('value in R = %f',u$doEval( 1 )))";
514 std::cout<<"value in ROOT = "<<TMath::BesselY1(1)<<std::endl;
516 ////////////////////////////////////////////////////////////
517 //creating a MyFunctor's object and passing object to R's //
518 //environment, the status should be true because is not //
519 //using the default function //
520 ////////////////////////////////////////////////////////////
522 functor.setFunction(TMath::Erf);
523 r["functor"]<<functor;
524 //printing the status that should be true
525 r<<"print(functor$getStatus())";
526 r<<"print(sprintf('value in R = %f',functor$doEval( 1 )))";
527 std::cout<<"value in ROOT = "<<TMath::Erf(1)<<std::endl;
531 ## Simple fitting in R and plot in ROOT
532 The next example creates an exponential fit.
533 The idea is to create a set of numbers x,y with noise from ROOT,
534 pass them to R and fit the data to `x^3`,
535 get the fitted coefficient(power) and plot the data,
536 the known function and the fitted function using ROOT's classes.
539 #include<TRInterface.h>
542 TCanvas *SimpleFitting(){
543 TCanvas *c1 = new TCanvas("c1","Curve Fitting",700,500);
546 // draw a frame to define the range
547 TMultiGraph *mg = new TMultiGraph();
549 // create the first graph (points with gaussian noise)
553 //Generate the points along a X^3 with noise
556 for (Int_t i = 0; i < n; i++) {
557 x1[i] = rg.Uniform(0, 1);
558 y1[i] = TMath::Power(x1[i], 3) + rg.Gaus() * 0.06;
561 TGraph *gr1 = new TGraph(n,x1,y1);
562 gr1->SetMarkerColor(kBlue);
563 gr1->SetMarkerStyle(8);
564 gr1->SetMarkerSize(1);
567 // create the second graph
568 TF1 *f_known=new TF1("f_known","pow(x,3)",0,1);
569 TGraph *gr2 = new TGraph(f_known);
570 gr2->SetMarkerColor(kRed);
571 gr2->SetMarkerStyle(8);
572 gr2->SetMarkerSize(1);
574 //passing data to Rfot fitting
575 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
576 r["x"]<<TVectorD(n, x1);
577 r["y"]<<TVectorD(n, y1);
578 //creating a R data frame
579 r<<"ds<-data.frame(x=x,y=y)";
580 //fitting x and y to X^power using Nonlinear Least Squares
581 r<<"m <- nls(y ~ I(x^power),data = ds, start = list(power = 1),trace = T)";
582 //getting the exponent
584 r["summary(m)$coefficients[1]"]>>power;
586 TF1 *f_fitted=new TF1("f_fitted","pow(x,[0])",0,1);
587 f_fitted->SetParameter(0,power);
588 //plotting the fitted function
589 TGraph *gr3 = new TGraph(f_fitted);
590 gr3->SetMarkerColor(kGreen);
591 gr3->SetMarkerStyle(8);
592 gr3->SetMarkerSize(1);
597 //displaying basic results
598 TPaveText *pt = new TPaveText(0.1,0.6,0.5,0.9,"brNDC");
599 pt->SetFillColor(18);
600 pt->SetTextAlign(12);
601 pt->AddText("Fitting x^power ");
602 pt->AddText(" \"Blue\" Points with gaussian noise to be fitted");
603 pt->AddText(" \"Red\" Known function x^3");
605 fmsg.Form(" \"Green\" Fitted function with power=%.4lf",power);
612 In the first image you can see the blue dots which are the function `x^3` with gaussian noise, the red dots correspond to
613 the original function and the green ones correspond to the fitted function.
615 \image html R_image1.png
617 ## Global Minimization in R using the package DEoptim
618 DEoptim is a R package for Differential Evolution Minimization that lets you do global
620 To install this package you just need to run:
623 #include<TRInterface.h>
624 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
625 r<<"install.packages('DEoptim',repos='http://cran.rstudio.com/')";
628 Then create a macro named GlobalMinimization.C with the next code.
631 #include<TRInterface.h>
632 #include<TBenchmark.h>
635 //In the next function the *double pointer should be changed by a TVectorD datatype,
636 //because the pointer has no meaning in the R environment.
637 //This is a generalization of the RosenBrock function, with the min xi=1 and i>0.
638 Double_t GenRosenBrock(const TVectorD xx )
640 int length=xx.GetNoElements();
643 for(int i=0;i<(length-1);i++)
645 result+=pow(1-xx[i],2)+100*pow(xx[i+1]-pow(xx[i],2),2);
651 Double_t Rastrigin(const TVectorD xx)
653 int length=xx.GetNoElements();
654 Double_t result=10*length;
655 for(int i=0;i<length;i++)
657 result+=xx[i]*xx[i]-10*cos(6.2831853*xx[i]);
662 void GlobalMinimization()
665 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
667 Bool_t installed=r.Eval("is.element('DEoptim', installed.packages()[,1])");
670 std::cout<<"Package DEoptim no installed in R"<<std::endl;
671 std::cout<<"Run install.packages('DEoptim') in R's environment"<<std::endl;
676 r<<"suppressMessages(library(DEoptim, quietly = TRUE))";
678 // passing RosenBrock function to R
679 r["GenRosenBrock"]<<GenRosenBrock;
681 //maximun number of iterations
683 //n = size of vector that is an argument for GenRosenBrock
686 r<<"ll<-rep(-25, n)";
690 bench.Start("GlobalMinimizationRosenBrock");
691 //calling minimization and timing it.
692 r<<"result1<-DEoptim(fn=GenRosenBrock,lower=ll,upper=ul,control=list(NP=10*n,itermax=MaxIter,trace=FALSE))";
693 std::cout<<"-----------------------------------------"<<std::endl;
694 std::cout<<"RosenBrock's minimum in: "<<std::endl;
695 r<<"print(result1$optim$bestmem)";
696 std::cout<<"Bechmark Times"<<std::endl;
698 bench.Show("GlobalMinimizationRosenBrock");
701 //passing RosenBrock function to R
702 r["Rastrigin"]<<Rastrigin;
703 //maximun number of iterations
705 //n = size of a vector which is an argument for Rastrigin
712 bench.Start("GlobalMinimizationRastrigin");
713 //calling minimization and timing it.
714 r<<"result2<-DEoptim(fn=Rastrigin,lower=ll,upper=ul,control=list(NP=10*n,itermax=MaxIter,trace=FALSE))";
715 std::cout<<"-----------------------------------------"<<std::endl;
716 std::cout<<"Rastrigin's minimum in: "<<std::endl;
717 r<<"print(result2$optim$bestmem)";
718 std::cout<<"Bechmark Times"<<std::endl;
720 bench.Show("GlobalMinimizationRastrigin");
721 r<<"dev.new(title='RosenBrock Convergence')";
722 r<<"plot(result1,type='o',pch='.')";
723 r<<"dev.new(title='Rastrigin Convergence')";
724 r<<"plot(result2,type='o',pch='.')";
727 In the image you can see the convergence plots of the functions and their minimum.
728 For RosenBrock is (1,1,1) and for Rastrigin is (0,0,0).
730 \image html R_image2.png
732 ## Interpolation (Plotting in R)
733 This example shows an interpolation using the function aproxfun and how to make a plot with R's
736 More Information on R interpolation
737 [here](http://stat.ethz.ch/R-manual/R-patched/library/stats/html/approxfun.html).
740 #include<TRInterface.h>
746 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
749 std::vector<Double_t> x(10),y(10);
750 for(int i=0;i<10;i++)
760 r<<"dev.new()";//Required to activate new window for plotting
761 //Plot parameter. Plotting using two rows and one column
762 r<<"par(mfrow = c(2,1))";
764 //plotting the points
765 r<<"plot(x, y, main = 'approx(.) and approxfun(.)')";
767 //The function "approx" returns a list with components x and y,
768 //containing n coordinates which interpolate the given data points according to the method (and rule) desired.
769 r<<"points(approx(x, y), col = 2, pch = '*')";
770 r<<"points(approx(x, y, method = 'constant'), col = 4, pch = '*')";
773 //The function "approxfun" returns a function performing (linear or constant)
774 //interpolation of the given data.
775 //For a given set of x values, this function will return the corresponding interpolated values.
776 r<<"f <- approxfun(x, y)";
778 r<<"curve(f(x), 0, 11, col = 'green2')";
782 //using approxfun with const method
783 r<<"fc <- approxfun(x, y, method = 'const')";
784 r<<"curve(fc(x), 0, 10, col = 'darkblue', add = TRUE)";
785 // different interpolation on left and right side :
786 r<<"plot(approxfun(x, y, rule = 2:1), 0, 11,col = 'tomato', add = TRUE, lty = 3, lwd = 2)";
789 The image shows the interpolated function plotted within R:
790 \image html R_image3.png
792 ## Integration (Passing vectorized function to R)
793 Numerical integration using R passing the function from ROOT
797 #include<TRInterface.h>
798 #include<Math/Integrator.h>
801 //To integrate using R the function must be vectorized
802 //The idea is just to receive a vector like an argument,to evaluate
803 //every element saving the result in another vector
804 //and return the resultant vector.
805 std::vector<Double_t> BreitWignerVectorized(std::vector<Double_t> xx)
807 std::vector<Double_t> result(xx.size());
808 for(Int_t i=0;i<xx.size();i++)
810 result[i]=TMath::BreitWigner(xx[i]);
815 double BreitWignerWrap( double x){
816 return TMath::BreitWigner(x);
823 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
825 r["BreitWigner"]=BreitWignerVectorized;
827 Double_t value=r.Eval("integrate(BreitWigner, lower = -2, upper = 2)$value");
829 std::cout.precision(18);
830 std::cout<<"Integral of the BreitWigner Function in the interval [-2, 2] R = "<<value<<std::endl;
833 ROOT::Math::WrappedFunction<> wf(BreitWignerWrap);
834 ROOT::Math::Integrator i(wf);
835 value=i.Integral(-2,2);
836 std::cout<<"Integral of the BreitWigner Function in the interval [-2, 2] MathMore = "<<value<<std::endl;
839 TF1 f1("BreitWigner","BreitWignerWrap(x)");
840 value=f1.Integral(-2,2);
841 std::cout<<"Integral of the BreitWigner Function in the interval [-2, 2] TF1 = "<<value<<std::endl;
844 value=r.Eval("integrate(BreitWigner, lower = -Inf, upper = Inf)$value");
845 std::cout<<"Integral of BreitWigner Function in the interval [-Inf, Inf] R = "<<value<<std::endl;
851 - http://oproject.org/tiki-index.php?page=ROOT+R+Users+Guide