Rcpp比传统的R API简洁易用,更加类似C++了。Rcpp采用的Robject管理R传来的对象,如: cpp::NumericVector ab = Rcpp::NumericVector::create(123.45, 67.89);创建一个2个值的数值型向量,可以直接用下标操作[]取到元素值。
Rcpp类型和R类型对照表:左边是Rcpp对象,右边是R对象,比如Rcpp::IntegerVecto在R中可以对应1:10
Rcpp class R 类型
Integer(Vector|Matrix) integer vectors and matrices
Numeric(Vector|Matrix) numeric ...
Logical(Vector|Matrix) logical ...
Character(Vector|Matrix) character ...
Complex(Vector|Matrix) complex ...
List list (aka generic vectors) ...
Expression(Vector|Matrix) expression ...
Environment environment
Function function
XPtr externalptr
Language language
S4 S4
Rcpp对象转为R对象:template <typename T> SEXP wrap(const T& object); //将Rcpp中对象转换为R对象,如将Rcpp中的int转为R中的numeric通常用于Rcpp返回值如return Rcpp:wrap(10)。wrap 的作用是将 C++ 的数据类型转换成 R 的数据类型,方便将C++ 的运算结果返回到 R 中
R的对象转换为Rcpp对象:template <typename T> T as(SEXP m_sexp); //as 的作用将 R 中的数据类型转换成 C++ 中的数据类型
Rcpp::Function
Rcpp::Environment
Rcpp::Formula
Rcpp::Language
例如:
#include <Rcpp.h> #include<iostream> #include <boost/array.hpp>//这里没有使用boost,只是想说明可以直接使用boost using namespace Rcpp; using namespace std; // [[Rcpp::export]] SEXP traverse(NumericMatrix x) {//NumericVector traverse(NumericMatrix x) cout<<"矩阵操作"<<endl; int nrow=x.nrow();//行数 int ncol=x.ncol();//列数 for(int i=0;i<nrow;i++){ for(int j=0;j<ncol;j++){ cout<<x(i,j)<<" ";//矩阵下标操作x(i,j) } cout<<endl; } cout<<"调用R内置函数"<<endl; Environment stats("package:stats"); Function rnorm=stats["rnorm"]; //If you don't know in advance what the output will be, //store it in an RObject or in components of a List. //特别是tapply这样的函数返回类型是list NumericVector a=as<NumericVector>(rnorm(3));//as的用法 for(NumericVector::iterator it=a.begin();it!=a.end();it++){ *it+=10; } a.names() = CharacterVector::create("a", "b", "c");//修改a的属性 a.attr("my-attr") = "my-value"; a.attr("class") = "my-class"; return Rcpp::wrap(a);//可以是return a相当于定义返回值为NumericVector//wrap的用法 } //下面是R脚本 /*** R #格式非得这样:/*** R x=matrix(1:16,4,4) traverse(x) */
int int_s = NA_INTEGER; String chr_s = NA_STRING; bool lgl_s = NA_LOGICAL; double num_s = NA_REAL;
http://adv-r.had.co.nz/Rcpp.html
http://cran.rstudio.com/web/packages/Rcpp/vignettes/Rcpp-quickref.pdf
http://www.jstatsoft.org/v40/i08/paper
http://cos.name/wp-content/uploads/2012/05/13-huangjinshan-Rcpp.pdf
一个例子,当然这个可以直接在C++中做,但是我数据在R里处理能直接通过Rcpp做的话当然方便。
文件数据部分大致是这样的:
row.names | V1 | V2 | V3 | V4 | V5 | V6 | |
---|---|---|---|---|---|---|---|
1 | 2013 | 11 | Neitui | Angel | Innovation Works|| | 4.00e-01 | |
2 | 2013 | 11 | Analyze Re | Seed | BDC Venture Capital|| | 1.40e+00 | |
3 | 2013 | 11 | Garantia Data | Series A | Bain Capital Ventures||Carmel Ventures|| | 9.00e+00 | |
4 | 2013 | 11 | BugBuster | Series A | Polytech Ventures|| | 1.10e+00 |
现在的目标是将列V5中||分隔开的数据分割成不同的行,其它部分保留。
开始我在R里面采用for循环的方式运行大概4万多条花了整整一晚上(一个中下配置的笔记本),现在我采用Rcpp运行大概其中26000多条数据,十几秒就能完成,突然感觉还是C++才是王道啊!
其中data01就是上面表格中的V1~V6的数据,是个DataFrame。
#include<Rcpp.h> #include<vector> #include<string> #include<fstream> #include<boost/algorithm/string/classification.hpp> #include<boost/algorithm/string/split.hpp> using namespace Rcpp; using namespace std; using namespace boost; // [[Rcpp::export]] void split(CharacterVector Year,CharacterVector Month,CharacterVector Com,CharacterVector Round,CharacterVector Investor,NumericVector Size){//这里有点缺憾就是直接传DataFrame进去无法索引下标(C++的矩阵是各列属性相同,但是DataFrame各列可以异构),所以只好选择每列作为一个向量参数 int len=Investor.size(); ofstream out("result.txt",ios::out); for(int i=0;i<len;i++){ vector<string> vec; string temp=as<string>(Investor[i]); boost::split(vec,temp,is_any_of("|"));//boost的字符串分割函数 for(vector<string>::iterator it=vec.begin();it!=vec.end();it++){ if(*it!=""){ out<<Year[i]<<"\t"<<Month[i]<<"\t"<<Com[i]<<"\t"<<Round[i]<<"\t"<<*it<<"\t"<<Size[i]<<endl; } } } } /*** R split(as.character(data01[,1]), as.character(data01[,2]), as.character(data01[,3]), as.character(data01[,4]), as.character(data01[,5]), as.numeric(data01[,6])) */
2013 11 Neitui Angel Innovation Works 0.4
2013 11 Analyze Re SeedBDC Venture Capital1.4
2013 11 Garantia Data Series ABain Capital Ventures9
2013 11 Garantia Data Series ACarmel Ventures9
2013 11 BugBuster Series APolytech Ventures1.1
2013 11 Hinge Series AGreat Oaks Venture Capital4
2013 11 Hinge Series AThe Social+Capital Partnership4