之前介绍了如何制作并发布自己的R语言包。这篇文章介绍怎么制作一个C++的R包,也就是使用Rcpp制作R包。
其实制作Rcpp的R包和普通的R包制作还是有区别的。本人也尝试按照之前的做法,在R脚本里面使用cppFunction()写一个C++脚本,以脚本运行的时候很完美,没有出现任何错误,但是当构建成包时,安装之后每次运行都出现错误。所以不得不尝试其他方法创建Rcpp的R包。
1、为什么要用Rcpp
Rcpp实际上是R语言调用C++的一个接口,而C++在运行速度上要比R语言快成百上千倍!!比如有如下两个数据:
其中aa$pos表示一段DNA序列的SNP位点,bb表示该DNA序列上的基因位置(包括基因起始位置和终止位置),如果你要判断aa中所有的SNP是否在基因上,我们通常的做法是写两个for循环,用aa中的每一个SNP位点去判断bb中的每一个基因。也就是要有3 * 3 = 9次运算。但是当数据量足够大的时候,假如有几十万SNP位点,有几万基因序列,那么这个循环可能要执行成百上千万次!这对R语言来说,运行时间会以小时来计了。
而C++可以在一两分钟内完成!
参考:
如何提升备受诟病的R的运行速度
2、构建RcppR包过程
(1)准备工作
和之前的介绍一样,还是要安装并加载devtools 和 roxygen2两个工具包。
然后创建一个路径(“~/Documents/CheckOverlap),在此路径内构建R包
和之前的文件结构不同,这时会出现一个src文件夹。
(2)写C++函数
按照你的目的参考如下格式写C++函数,并将该文件保存成“~/Documents/CheckOverlap/src/CheckPointRange.cpp“。
如果是在Rstudio中,可以“新建” —“C++文件“,这样会自动生成一个模版。
注意,这儿写了两个函数,一个是用来判断SNP是够在基因上(CheckPoint),另一个用来判断基因上是否含有SNP位点(CheckRange)。
其中很多关键字是不可缺少的,比如include, using, useDynLib 你的包名, import, export, [[Rcpp::export]]等。
然后
或者在Rstudio点击“Source“
(3)建包
这个时候去检查CheckOverlap文件夹,会有很多自动生成的文件,包括NAMESPACE、DESCRIPTION,在src子文件夹中,有.so, .o等文件名后缀的的文件。
在R子文件夹中,出现了一个RcppExports.R的文件,这个文件就相当于该包的主文件。
下面检查包,看看是否存在错误。
(4)本地安装并调试
输出结果为
至此,R包的构建已经完成
3、R包发布
设置GitHub账户,参考:
https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/
https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/
在自己的GitHub账户上创建一个目录,用来存放你要发布的R包。
在本地terminal中:
创建,发布;全部完成!
一个需要几个小时完成的任务,现在只需要一两分钟就可以完成!
======= THE END =======
参考资料:
https://www.r-bloggers.com/rcpp-and-roxygen2/
http://www.deanbodenham.com/learn/make-an-r-package-using-rcpp.html
领取专属 10元无门槛券
私享最新 技术干货