0%

R package development - as a beginner

对团队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注释包含以下几块内容,可查阅:

假如是多人协作,最好大家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包开发初始的基本框架和注意事项,有问题可随时沟通

参考资料

为新手准备的现代化 R 包开发流程

R包制作和roxygen2使用说明

本文出自于http://www.bioinfo-scrounger.com转载请注明出处