对团队R包开发的协作经验,做个小结;并为个人开发R包做个基础知识准备
准备工作
基础知识准备,查阅以下文档:
创建R包
首先确定R包的名称,可遵循以下规则(搬抄自:What's in a Name)
- must start with letter
- no underscores
- periods allowable or use CamelCase
- can have numbers
- should be Google-able
可以用available
包来检查下名字是否被使用,NOTE:非常实用!
available::available("mcIVD", browse = FALSE) # if want "mcIVD"
使用usethis
包的usethis::create_package()
函数创建R包,R包开发中的一些列操作都可依靠这个包,各个函数的用法可参考:https://usethis.r-lib.org/reference/index.html
install.packages(c("devtools", "usethis"))
# Create a new package
usethis::create_package("~/newPackage")
R包一般的基本结构:
- Functions
- Documents
- Data
- Vignettes
- Versions
- Dependencies
版本控制(Git)
对于github command line用的不熟练的人(比如我自己),建议使用Github Desktpp或者GitKraken,我觉得后者更加好用点,尤其是多人协作开发R包;最后push到Github上
代码规范
不管是个人开发还是多人协作开发,都要注意自己的R编码习惯,Google有个R语言编码风格指南可供参考,如来自 Google 的 R 语言编码风格指南
其中有几条值得特别注意:
- 最大单行长度为 80 个字符.
- 使用两个空格来缩进代码. 永远不要使用制表符或混合使用二者.
- ......
此外还有函数和方法等命名方式,函数我习惯于用下划线,方法用大小写,不知道这样合不合适。。。
一般建议用styler
包来统一规范代码格式
install.packages("styler")
然后在Rstudio的Addins中选择适用的规范方式,如Style active file.
R包的描述说明
一般R的描述说明是放在DESCRIPTION文件中,在R包创建之时就应该定义一部分内容,剩下的在后续R包开发中持续更新
这个部分内容可以参考其他成熟R包的写法,copy and modify即可
其中Imports和Suggests区别如下:
Imports是指必需引用的包,在安装的时候,若这些包还未被安装,则会持行安装程序
如果只是使用某些包中类、方法或者(一般)函数,而不用完全载入包,可以在此栏列出包的名称,最好加上版本号(在R CMD check会检查版本)。在代码中,引用其他包的namespace可以使用
::
或者:::
操作符。与之对应的,需要在NAMESPACE文件中指明引用Suggests是指建议安装的包,可能在示例数据,运行测试,创建vignettes或者包里面只有少量函数使用这些包,因此我们只需要在使用函数前检查这些包是否被安装
如果只是在帮助文档的examples,tests或者vignettes中用到了一些包,那么没有必要“依赖”或者“引用”,只用“建议”安装即可。版本号同样也要加上,在R CMD check时会用到。当然,我们要考虑到如果读者也想重现一下examples/tests/vignettes的例子,最好使用
if(require(pkgname)))
的条件句控制:TRUE执行,FALSE返回错误。
Depends和Imports的区别如下:
- Depends和Imports的唯一的区别就是,Depends会attach包;而Imports只load包
- 一般情况下只需在Imports里面列出需要的包,写函数的时候使用
::
来获取需要的函数;另外Imports或者Depends里面的包在安装的时候如果没有安装会自动安装,确保我们可以使用::
单独使用Imports、Depends和Suggests引用的都是CRAN上的包,如果想引用Bioconductor上的包,需要在前面加上biocViews:
此外还有些usethis
包对DESCRIPTION文档的操作,如:
# 升级版本号
usethis::use_version()
BugReports:一个网址,用于提交bug,代替了向作者发邮件。一个好的想法是使用Github,在项目的issures版块提交bug。
编写函数
一般来说,R包的函数会放在R
子目录下
当编写函数时,不要忘记添加roxygen
格式的注释,点击Insert Roxygen Skeleton
快速生成文档骨架
注释完成后,使用devtools::document()
在man
子目录下生成函数文档,这些操作都有快捷方式以及Rstudio中的按键,看个人习惯
一般Roxygen注释包含以下几块内容,可查阅:
- https://cran.r-project.org/web/packages/roxygen2/vignettes/rd.html
- https://cran.r-project.org/web/packages/roxygen2/vignettes/roxygen2.html
假如是多人协作,最好大家Roxygen格式都保持一致
尤其是一些注释习惯保持一致,如title不要用动词开头,尽量保持名词化等等;
选择面向对象系统类型
一般来说,官方制定的类型系统有四种:基础类型、S3类型、S4类型和RC类型;Bioconductor收录的R包一般都是S4类型;S3相比S4更加宽松点,所以也更加简单点,但是不robust。
可参考:Advanced R
测试代码
对于一个复杂的R包,给函数或者方法编写对应的测试代码是非常有必要的,可使用testthat
来实现
非常重要,虽然编写test代码会多增加一点工作量,但是实际使用中却可以节约很多调试的时间
# 增加测试环境
usethis::use_testthat()
# 安装testthat
install.packages("testthat")
对于每个test_*.R
代码的单独测试,可在Rstuido中点击Run Tests来执行。
制作包的说明页
我们在一些成熟的R包中可看到,其有个文档网页,或者说是Guidance以供用户查阅;
先在github page页生成一个网址(Privite库不支持,必须public库哈),然后安装pkgdown
包
install.packages("pkgdown")
初始化后,可手动修改_pkgdown.yml
文件来自定义,然后push到Github上
usethis::use_pkgdown()
`pkgdown::build_site()`
再Github repo的Setting中修改,最后refresh网站
其他可参考:https://pkgdown.r-lib.org/articles/pkgdown.html
创建Vignettes
Vignettes一般对于成熟的R是必备的
usethis::use_vignette("my-vignette")
参考:https://r-pkgs.org/vignettes.html
其他
增加一些external data 和internal data,data-raw
文件夹存放internal data的code,data
文件夹存档raw data
对应clean-up版的Rdata,以及一些Rdata document的R代码
此外还可以将一些需要parse的raw data 放在inst/extdata
中,可用system.file()
调用
增加一些其他文档来补充下R包的整体框架,如NEWS.md
usethis::use_news_md()
比如只想要pipe(%>%
),但不要import dplyr
包,则:
usethis::use_pipe()
创建一个README.Rmd
文档
usethis::use_readme_rmd()
值得注意的是,每次想push comments或merge分支的时候,记得check下整个R包,看看是否有errors未解决
还有Spell Checking,CRAN会检查拼写(或者增加一个WORDLIST文件用于标注一些正确的拼写),如:
devtools::spell_check()
# after you have fixed the issues, run
spelling::update_wordlist()
此外制作一个Logo/Hex Sticker,可参考:Owning a hex sticker,或者直接使用hexSticker
包
以上为我所整理的R包开发初始的基本框架和注意事项,有问题可随时沟通
参考资料
本文出自于http://www.bioinfo-scrounger.com转载请注明出处