参考:R package: https://r-pkgs.org/index.html
开发R包的过程中主要的R包就是devtools
,为了更好地演示foofactors
这个包的开发过程,还需要载入
library(tidyverse)#涉及数据处理
library(fs)#方便操作文件系统
Toy package: foofactors
这个用来演示R包开发过程的foofactors是为了使得factor的处理更方便,仅做示例
在开源的R包开发中,往往会有:
- 具体解决某个问题的函数
- 完整的workflow,从install到怎么获得帮助文档、检查包的质量等
- 包的版本控制,涉及Git和Github
- 对于单个函数的文档说明,这个通过roxygen2搞定
- 对包的细节问题进行检查: testthat.
- 最后对整个包做全面的介绍,用 可执行的
README.Rmd
就可制作。
这里作者给出了成品的foofactors的样子:https://github.com/jennybc/foofactors
Step1
新建项目
注意这个项目一定是独立的,不要嵌合在其他已有的Rproj或者Git repository里面。
create_package("~/path/to/foofactors")
目录下面自动生成:
#> # A tibble: 6 x 2
#> path type
#> <fs::path> <fct>
#> 1 .Rbuildignore file #展示R包创建时需要哪些文件,不过这个在从source上建立R包时不需要
#> 2 .gitignore file #典型的git里的文件,说明哪些文件的commit需要忽略
#> 3 DESCRIPTION file #包的metadata
#> 4 NAMESPACE file #声明exports和imports,可被哪些包导入以及需要导入哪些包
#> 5 R directory #R脚本,放独立的函数文件
#> 6 foofactors.Rproj file #普通R项目的文件
现在我们新建的是一个R studio proj,把它变成Git repository, with use_git()
.
use_git()
#> ✔ Initialising Git repo
#> ✔ Adding '.Rhistory', '.RData' to '.gitignore'
在Git的交互式运行界面上会有commit的提示:此时目录下多了一个.git文件夹
#> [bdb30c7] 2019-09-10: Initial commit
#> # A tibble: 1 x 2
#> path type
#> <fs::path> <fct>
#> 1 .git directory
Step2
Write the first function
函数的目的是为了更好地连接因子变量并显示具体的因子,而不是原本的只展示数字:
(a <- factor(c("character", "hits", "your", "eyeballs")))
#> [1] character hits your eyeballs
#> Levels: character eyeballs hits your
(b <- factor(c("but", "integer", "where it", "counts")))
#> [1] but integer where it counts
#> Levels: but counts integer where it
c(a, b)
#> [1] 1 3 4 2 1 3 4 2
可以看到一般把因子变量连接起来的问题,输出的是数字,这不是我们想要的,理论上希望的是这样:
factor(c(as.character(a), as.character(b)))
#> [1] character hits your eyeballs but integer where it
#> [8] counts
#> Levels: but character counts eyeballs hits integer where it your
把上面包装成函数:
fbind <- function(a, b) {
factor(c(as.character(a), as.character(b)))
}
注意要把这个函数单独保存在一个.R文件中,在R目录下。可以用这个函数:新建一个名叫fbind的Rscript,然后往里面添加函数内容即可:
use_r("fbind")
#> ● Edit 'R/fbind.R'
load_all()
类似平常要使用函数时需要先用source加载到环境中,在R包开发中有点不一样的是,用的load_all()函数,使得我们刚写的fbind函数可以使用:
load_all()
#> Loading foofactors
fbind(a, b)
#> [1] character hits your eyeballs but integer where it
#> [8] counts
#> Levels: but character counts eyeballs hits integer where it your
不过这个fbind虽然可使用却并不在当前的全局工作空间里面,这也是load_all()的特点
load_all()
simulates the process of building, installing, and attaching the foofactors package
每完成一个函数,就可以提交一次commit:
#> [b3fc569] 2019-09-10: Add fbind()
#> diff --git a/R/fbind.R b/R/fbind.R
#> new file mode 100644
#> index 0000000..7b03d75
#> --- /dev/null
#> +++ b/R/fbind.R
#> @@ -0,0 +1,3 @@
#> +fbind <- function(a, b) {
#> + factor(c(as.character(a), as.character(b)))
#> +}
Step3
check()
在中断用R CMD check或者直接在Rstudio里用check()函数:检查包里的问题
我这里截取了最后的一些warning:
> checking DESCRIPTION meta-information ... WARNING
Non-standard license specification:
What license it uses
Standardizable: FALSE
> checking for missing documentation entries ... WARNING
Undocumented code objects:
'fbind'
All user-level objects in a package should have documentation entries.
See chapter 'Writing R documentation files' in the 'Writing R
Extensions' manual.
0 errors √ | 2 warnings x | 0 notes √
注意一定要及时检查check的输出结果!这里有两个warnings:
Non-standard license specification
Undocumented code objects: 'fbind'
接下来我们会逐步解决这些问题。
网友评论