R包开发书籍:https://r-pkgs.org/whole-game.html
R包开发简单流程
library(devtools)
packageVersion("devtools")
library(tidyverse) # 数据轻量级处理
library(fs) # 文件系统处理
create_package("F:\\R-packages\\foofactors") # 通过双击foofactors.Rproj进入开发界面
use_git() # 使开发包成为一个git库
dir_info(all = TRUE, regexp = "^[.]git$") %>% # 查找文件夹
select(path, type)
use_r() # 在开发包中创建一个R脚本存储函数
load_all() # 加载新创建的函数到环境中
check() # 检查函数的可靠性
use_mit_license("Hongyu Chen") # 设置R包服从的协议
# 在使用roxygen2包后需要先运行document()函数,最后会生成man文件夹
R包开发前期准备
install.packages(c("devtools", "roxygen2", "testthat", "knitr"))
R包-DESCRIPTION部分
##### 依赖
# Imports标注必须安装的包
# Suggests标注非必须的包
# 添加Imports和Suggests最简单的方法是使用devtools::use_package()
devtools::use_package("dplyr") # 默认为imports
# 指定特定的版本
Imports:
ggvis (>= 0.2),
dplyr (>= 0.3.0.1)
Suggests:
MASS (>= 7.3.0)
# 指定需要的R版本--Depends
devtools::create()
# LinkingTo 列出包依赖于另一个包中的 C或C++代码
# Enhances 不建议使用
#### 标题和描述
Description部分可以为多个句子,但从第二行开始需要增加四个空格,其次每行不能超过80个字符
#### 作者 -- Author@R
Authors@R: person("Hadley", "Wickham", email = "hadley@rstudio.com",
role = c("aut", "cre"))
# aut 指包的作者;cre 指包的维护者;ctb 贡献者;cph 版权所有人
Authors@R: c(
person("Hadley", "Wickham", email = "hadley@rstudio.com", role = "cre"),
person("Winston", "Chang", email = "winston@rstudio.com", role = "aut"))
#### 许可证
# 三种许可证:MIT、GPL-2、CC0 (权限依次升高)
#### 版本号
<主版本号><次版本号><补丁版本>
对象文档
对象文档也就相当于对包以及包中的函数进行解释,一般在R包的man目录下会存在.Rd文档
#### 文档工作流程
1. 添加roxygen注释到.R文件
2. 运行devtools::document()
3. 利用?预览文档
4. 修改注释,重复上述步骤
介绍块
@在roxygen中具有特殊意义,如果想要添加需要使用@@
@section 标签在文档中添加任意的块
@seealso 指向其他有用的资源
@family 如果有一族相关的函数,每个函数都应该链接到族中的其他函数
@aliases 增加别名
@keywords 增加标准化的关键词
函数块
@param 名字 描述
@examples 提供可执行的R代码 \dontrun{} 可以让你在实例中包括无需运行的代码
@return 返回值描述
包文档
为NULL提供文档
#' foo: A package for computating the notorious bar statistic.
#'
#' The foo package provides three categories of important functions:
#' foo, bar and baz.
#'
#' @section Foo functions:
#' The foo functions ...
#'
#' @docType package
#' @name foo
NULL
一般存在为叫作<包名>.R的文件中
长篇文档
# 查看安装包的使用指南
browseVignettes()
browseVignettes("包名“)
vignette() # 阅读指定部分(源文件、html文件、R代码文件)
# knitr提供R Markdown使用指南引擎
# pandoc协调Markdown和knitr之间的工作,且提供较多的模板将markdown转换为html
# 创建使用指南
devtools::use_vignette("my-vignette") # 旧版本使用
usethis::use_vignette("my_vignette")
测试
# 利用testthat进行自动化测试
devtools::use_testthat()
# 测试结构组成--期望
1. 它们以 expect_ 开始。
2. 它们有两个参数:第一个是实际结果,第二个是期望值。
3. 如果实际结果与预期不一致,testthat 将抛出一个错误。
expect_equal() 和 expect_identical()测试相等的基本方法,expect_match() 检查一个字符向量是否和一个正则表达式匹配。 expect_output() 检查打印输出; expect_message() 检查消息; expect_warning() 检查警告; expect_error() 检查错误。expect_is() 检查对象是否从指定的类 inherit() (继承)。
命名空间
命名空间以两种方式让包相对独立:Import和Export
Import 定义一个包中的函数如何找到另一个包中的函数。
Export 指定哪些函数可在包外使用(内部函数只在包内可用,并不能很容易地被另一个包使用),以此帮助你避免与其他包冲突。
R搜索路径:1.全局环境下找 2.在搜索路径中你已经??的所有包中寻找;可通过search()查看
加载与附加的区别:加载后,该包就会在内存中,但它不在搜索路径中。附加一个已加载的包会将包放在搜索路径中。
Imports 只是加载包, Depends 附加包。
永远不要在包里面使用library()
# roxygen2包生成NAMESPACE文件
# 要导出一个对象,在它的 roxygen 块中放入 @export
# 可以设置util.R文件来记录一些不需要导出的小函数
# 导入
# 如果你只是使用了其他包的几个函数,我的建议是在 DESCRIPTION 文件的 Imports 域列
出包,然后调用函数时显式地使用 ::
外部数据
• 如果你想存储二进制数据,并把它提供给用户,就把它放在 data/ 目录。这是放示例数
据集最好的地方。
• 如果你想存储解析过的数据,但不将它提供给用户,就把它放在 R/sysdata.rda。这是存
放函数所需数据的最佳场所。
• 如果你想存储原始数据,则把它放在 inst/extdata。
导出的数据也需要文档:同样使用roxygen2完成,其中@format记录数据集的概述,@source提供数据来源的细节
编译过的代码
重点使用Rcpp包,但需要重新学习C++/C的代码编写,过于复杂
devtools::use_rcpp()
安装文件
主要需要配置inst目录下的文件,主要需要增加包的引用文件;citHeader(),citEntry()
自动检查
R CMD check or devtools::check()
- 检查元数据
- 包的结构
- 描述
- 命名空间
- 代码
- 数据
- 文档
- 演示
- 编译过的代码
- 测试
- 使用指南