目录
4-添加C++函数
5-编辑元数据
6-启用Roxygen,执行文档化。
7-单元测试
8-在自己的计算机上安装R包:
9-程序发布
参考:
为什么要写这篇文章的更新日期?因为R语言发展很快,很多函数或者方式,现在可以使用,不代表之后的若干年之后,还可以用,可能那个时候有更方便且快捷的操作方式。
有的时候,为了让R代码运行速度快一些,可能会借助一些编译语言,如C++。R是一门高级的、富有表现力的语言,但这事以速度为代价的,这就是为什么结合低级的编译语言(如C或者C++)可以有力地补充你的代码。虽然C和C++往往需要更多的代码行(和更仔细地思考)来解决同样地问题,但它们的速度可以比R快上几个数量级。
cpp = c plus plus = c++
c++函数函数可以直接在R中使用的接口为 Rcpp包(名字取得很好,R和C++)
usethis::use_rcpp("mean_rcpp")#生成一个mean_rcpp的c++文件
这个代码做了如下工作:
- 创建一个src/目录以存放.cpp文件;
- 在DESCRIPTION的LinkingTo和Imports域添加Rcpp;
- 建立一个.gitignore文件,确保你不会无意中提交任何已编译的文件;
- 在console中告诉你,需要你手动添加到报中的两个roxygen标签。(这条的具体细节在接下来的内容中会涉及到,这里不展开了。)
注意:C++代码都放在src/目录文件夹,R代码都放在R/目录文件夹,scr/目录这个文件夹是usethis::use_rcpp("c++函数名")自动生成。
在https://github.com/coatless-r-n-d/rcpp-and-doparallel/tree/master/src 中找到我们想要生成的mena_rcpp.cpp文件,打开复制里面的内容到 我们当前打开的cpp文件。
展示运行use_rcpp函数后console中的结果,√号表示这个函数完成的操作,●表示需要我们手动进行的操作。
> usethis::use_rcpp("mean_rcpp") ✔ Adding 'Rcpp' to LinkingTo field in DESCRIPTION ✔ Adding 'Rcpp' to Imports field in DESCRIPTION • Copy and paste the following lines into 'R/ReproduceRcpp2doParallel-package.R': ## usethis namespace: start #' @importFrom Rcpp sourceCpp ## usethis namespace: end NULL [Copied to clipboard] ✔ Creating 'src/' ✔ Adding '*.o', '*.so', '*.dll' to 'src/.gitignore' • Copy and paste the following lines into 'R/ReproduceRcpp2doParallel-package.R': ## usethis namespace: start #' @useDynLib ReproduceRcpp2doParallel, .registration = TRUE ## usethis namespace: end NULL [Copied to clipboard] ✔ Writing 'src/mean_rcpp.cpp' • Modify 'src/mean_rcpp.cpp'
可以看到√号完成的工作内容在本文usethis::use_rcpp("mean_rcpp")函数介绍那已经介绍过了,我们重点来看下●的部分。一共有三个●,具体来说:
每个包都必须有一个DESCRIPTION文件,它用来存放关于创建的R包的重要元数据。
打开DESCRIPTION文件,包名、编码等部分信息都是自己生成的,包括可编辑标题(单行文字)、版本号、作者、描述(一段文字)、网址等信息,导入、许可等信息更简易通过命令添加。
use_gpl_license(version = 2)
LazyData为true,确保加载包时自动惰性加载(使用时才载入内存)内部数据集。
查看下面的目标,通过上述介绍的命令完成(1)添加依赖包,(2)选择许可(3)其他一些修改(如Title,作者等信息,这个不修改也可以,不影响我们复现这个R包)
测试时开发R包的重要部分,可以确保代码更加稳健,能成功地实现相关的功能。
测试的一般原则是,设想函数可能遇到的各种情况下,是否都能得到预期的结果。策略之一是每当你遇到一个bug,就为它写一个测试,来检查函数是否能得到预期的结果。
虽然通过执行load_all()模拟加载包,可以在控制台做一些函数测试,但是更好的做法是采用testthat包提供的单元测试,这是一种正式的自动化测试。
具体操作如下:
先初始化包的单元测试:
use_testthat()
它将Suggests::testthat添加到DESCRIPTION,创建目录tests/testthat/,并添加脚本test/testthat.R。
打开或创建针对某函数的测试文件:
use_test("mean_parallel_compute")
测试文件是由若干个test_that()构成,第一个参数是对测试的描述,测试内容是大括号内的代码块,一般是比较函数返回值与期望值是否(近似)相等、是否复合类型等。
然后执行测试(若测试结果全为PASS,则表示通过测试):
test()
如果单元测试没有问题,再执行R CMD check检测
check()
在控制台会输出潜在错误、警告、注意的具体反馈,我们希望三者都是0。
Build --> Install package
开发完的R包,如果愿意开源给其他人使用,有几个发布平台供选择:CRAN、GitHub。
由于CRAN平台有各种审查,不允许随便发布,那么我们就先把程序发布到GitHub上面,等功能完善后,再申请提交到CRAN。把项目上传到GitHub的操作,和R语言没有什么关系。
操作步骤为:Git--> Staged--> Commit --> Push(下面会展示具体操作细节),将包的相关文件推送到GitHub远程仓库,换句话说,将包发布到GitHub,从而别人可以从GitHub上通过devtools包可以安装和使用你的R包。
具体步骤:
通过这种方式,您可以使用RStudio Server轻松暂存、提交和推送到GitHub。
Setup an R-Package with Rcpp in RStudio | Sebastian Hanß
《R语言编程》(张敬信,2023年2月,人民邮电出版社)(这本书写的很全面且细致,没有多余的废话。)
《R包开发》(Hadley, 2016年8月,人民邮电出版社)(这本书出版的时间比较长,书中有部分函数发生了调整。)
R Packages (2e) (r-pkgs.org) (这是是R包开发的第二版,较第一版有了些内容的调整和删减,下面截图是这本书的内容,左侧是目录,右侧是正文。值得花时间阅读。)
《R的极客理想:高级开发篇》(张丹,2015年7月,机工社)
Introduction to Computational and Data Sciences (这本书也超棒!很细节。本文第9节参考的是这本书的第4.9节)
RStudio制作包含Rcpp代码的R包_rcpp package_Kanny广小隶的博客-CSDN博客
注:写CSDN一定要少用Ctrl+Z呀,有时候撤回的不是一步。
这是R package 2ed的截图