R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)

R包介绍及开发(初学者基础详解)

  • 一、R包概述
    • 1.1 R包简介
    • 1.2 R包下载
    • 1.3 R包安装
    • 1.4 R包使用
  • 二、创建R包
    • 2.1 R包架构及内容
    • 2.2 R包开发的环境配置
      • 2.2.1 R包开发准备
      • 2.2.2 R包构建工具准备
        • 2.2.2.1 R包开发工具包 | devtools包
        • 2.2.2.2 工具集 | RTools
    • 2.3 R包创建流程
      • 2.3.1 命名 | 创建R包
        • 2.3.1.1 R包命名规则
        • 2.3.1.2 R包创建流程
      • 2.3.2 利用 “devtools+Rstudio” 开发R包
        • 2.3.2.1 新建项目(package name | 工作路径)
        • 2.3.2.2 编写 DESCRIPTION | file.edit()
        • 2.3.2.3 添加R包内置数据文件及函数 | usethis::use_data( ) (开发R包核心)
        • 2.3.2.4 编写R包函数说明文档 DOCUMENT | devtools::document()
        • 2.3.2.5 R包测试 | testthat
        • 2.3.2.6 生成项目说明文档 | usethis::use_vignette()
        • 2.3.2.7 检查R包 | devtools::check()
        • 2.3.2.8 生成R包 | devtools::build()
        • 2.3.2.9 发布R包 | devtools::build()
    • 2.4 总结

一、R包概述

1.1 R包简介

R作为一个开源软件,自身已包含多个不同功能的包,CRAN官方R包 >18000,利用R可轻松实现统计计算,数据可视化等功能。

在R中,R 函数可以用来解决问题,R包是可以分享代码的基本单位,把具有相关功能的 R 函数打包起来。
R包把代码,数据,文档和测试内容整合在一起,从而便于分享。

总的来说,R 包是由社区开发(developed by the community)的功能(functions)和数据集(data sets)的集合。
参考:R 包初学者指南。

1.2 R包下载

存储库(repository)用来存储R包,可以从存储库中下载及安装 R 包,包括本地存储库在线公开存储库

R 软件包最常用的三个存储库是:

  • CRAN:官方存储库,是一个由全球 R 社区维护的 ftp 和 Web 服务器网络。 它是由志愿者及 R 基金会协调维护,对于要在此发布的包,需要遵循 CRAN 策略。 详见:CRAN Repository Policy。
  • Bioconductor:专题库,用于生物信息学的开源软件。每年发布两个版本,拥有较活跃的用户社群。
  • Github:在线源代码保管平台,可能是开源项目中最受欢迎的存储库。 优势为无限的开源空间,与 git 的集成,版本控制软件以及与其他人共享和协作的便利性。

1.3 R包安装

R包安装有4种常见方式:

  • CRAN安装(CRAN镜像安装)
  • Bioconductor安装
  • Github安装
  • 手动安装

具体操作可以参照以下内容:
R: R package安装的几种方式
R语言入门之R包的安装

R包更新及删除参考:R 包初学者指南

1.4 R包使用

(1)下载安装R包后,加载R包,查询R包帮助文档

# 以从CRAN下载安装包为例
install.packages("package")

# 查看R包安装位置
.libPaths()
[1] "C:/R/R-4.0.5/library"

# 查看R包版本
packageVersion("devtools")
[1]2.4.3’

# 在R中加载包
library("package")

# 查看已加载的Rsearch()
 [1] ".GlobalEnv"        "package:devtools"  "package:usethis"   "tools:rstudio"     "package:stats"     "package:graphics" 
 [7] "package:grDevices" "package:utils"     "package:datasets"  "package:methods"   "Autoloads"         "org:r-lib"        
[13] "package:base"  

# 加载特定R包内置数据
load("F:/R_Iris/_R_packages/hello/data/cities.rda")

# 获取R包的帮助文档
package?package 
help(package = "package")

# 获取R包函数的帮助文档
?package
??package

(2)package()、library()、source()及option()的区别

  • package
即R包,包含明确定义格式的 R 函数、数据和编译代码等,用于添加特定功能
  • library()
即R中R包的存储目录。

library(package),会加载名为**package**的R包,并添加到包的搜索列表中。
加载前对搜索列表进行检查并更新,若package不存在则报错,若已加载package,则不会重复加载。

library(),则列出lib.loc指定的库中的所有可用包。
library(help=package)将返回package的基本信息。
  • require()
与library(package)类似。
加载前对搜索列表进行检查并更新,如果package不存在(不可用),则返回FALSE;若存在可用则返回TRUE。
  • source()
source() 使R直接调用指定本地路径下的脚本文件、接收URL或表达式的输入。脚本代码。

利用source从该指定文件读取函数,则脚本的每一行代码均会运行。
如: source("F:/R_Iris/_R_packages/R_packages.R", encoding = 'UTF-8'),会运行 "R_packages.R" 文件中的所有代码。

相比之下,library() 只调用R包代码,只包含对象,即定义的特定函数。
  • option()
设置全局变量

参考内容:
Packages and libraries
R包开发:source and libraries
DIFFERENCE BETWEEN library() AND require() IN R
source: Read R Code from a File, a Connection or Expressions
R语言环境变量的设置 环境设置函数为options()

二、创建R包

2.1 R包架构及内容

(1)以devtools包为例,解释R包结构,如下图所示:
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第1张图片
图1 devtools包架构示例

(2)一个 R 包的根目录,源代码 (source) 文件夹中通常包含两个文件若干子文件夹蓝色表示必须有的内容。

  • 文件包括 DESCRIPTIONNAMESPACE
    DESCRIPTION:纯文本文件,描述R包信息(包名、版本号、标题、描述、依赖关系等);
    – 包名:Package: package name;
    – R包类型:Type: package;(R-Project类型,R包为 “package”)
    – 版本号:Version
    – 标题:Title: What the package does(简要描述R包功能)
    – 描述:Description: 详细描述R包功能
    – 依赖关系:Depends: 所用开发环境需要的R版本,包括Imports和Suggests两种表达方式
    – 日期:Date: 该R包建立时间
    – 作者:Author
    – 维护者:Maintainer
    – R包许可证:License

    NAMESPACE:R包的命名空间文件,利用roxygen2生成,表示调用其他R包的具体函数,及可被其他R包调用的函数;即指定R包输入和输出的包,还有一些特殊的名称。
    其他文件包括
    – 描述 R 包更新的 NEWS, ChangeLog;
    – 描述协议的 LICENSE 或 LICENCE, INDEX, configure, cleanup 等.

  • 若干子文件夹包含其他文件, 包括 R, data, demo, exec, docs, inst, man, po, src, tests, tools 和 vignettes 等文件夹
    (这些文件夹有的是可以没有或空的, 有的必须要有并且不为空, 不同的包不同)。

    R:定义的R函数目录,包含所有R包中定义的函数,并以**.R格式保存的源码;
    man”:
    .Rd格式**的帮助文档,存放函数说明文件的目录;
    vignettes”: 包含了R包的使用指导文件,可用rmarkdown写;
    tests”: R包函数的测试目录,包含R包中定义函数及包功能的测试。
    data”: R包中的数据文件,建议.rda格式;
    docs”:R包运行结果示例;

    注:通常R会在man目录下自动创建与R目录下的函数对应的.Rd文件,一个额外的用以描述整个R包情况xxx-Package.Rd文件。

  • 除了以上所列内容, 源代码 (source) 文件夹中也可以放其他自行添加的文件或文件夹, 但是会被 R 忽略。

参考内容
R 学习笔记:Package 基础
制作自己的R包
R包简单教程
R包元数据
在CRAN上发布自己的R包
R包开发:构架及基础
R包编写详细教程

2.2 R包开发的环境配置

2.2.1 R包开发准备

本文所创建内容均基于Windows 10, 64位系统完成。在进行R包开发前,需准备以下内容:

  • 电脑系统:Windows 10, 64位;
  • Rsudio: RStudio 2022.02.3+492,Rsudio下载链接;
  • R:Version 4.0.5,R下载链接。
  • 环境变量路径设置

若从源代码构建 R 包,还需要一个编译器及其他一些命令行工具。

  • RTools软件:Toolchains for building R and R packages from source on Windows. 下载链接。
  • R包:“devtools”, “roxygen2”, “testthat”, “knitr”。

注:不能含有中文路径,否则后续 R包系统检查 check() 会报错,见2.3.2.7节。

2.2.2 R包构建工具准备

2.2.2.1 R包开发工具包 | devtools包

R包开发的目的是用函数实现自动化,减少手动操作。R包开发是基于devtools 开发包来实现

devtools包可以看作是元程序包( meta-package ),与使用较为普遍的开发环境Rstudio联合,使得R包开发更轻松便捷。

devtools 包可以调用 roxygen2 包, roxygen2则会将按特殊语法写在 R 代码文件中的信息转化为含有 R 函数说明的 man 文件。

(1)通过运行以下代码,安装R包开发所需的必备包:

  • devtools:辅助创建R包源代码;
  • roxygen:添加R包注释;
  • testthat:单元测试,测试R包代码;
  • knitr:生成动态报告。
# 批量安装所需R包
install.packages(c("devtools", "roxygen2", "testthat", "knitr"))

(2)通过运行以下代码,可以检查是否已安装所有组件并正常工作:

> has_devel()
Your system is ready to build packages!

> library(devtools)
载入需要的程辑包:usethis

(3)其他R包

  • rstudioapi:获取及设置工作路径等。
# rstudioapi安装
install.packages("rstudioapi")
#查看特定版本是否运行
rstudioapi::isAvailable("0.13")

关于R包开发的理论介绍详见:
R包开发-简介。
制作自己的R包

2.2.2.2 工具集 | RTools

在 Windows 上,从源代码创建R包所需的工具集叫 RToolsRtools是制作R包最重要也是最主要的工具。

Rtools包含了windows环境下制作R包的一系列工具,包括:

  • CYGWIN,用以在windows环境模拟UNIX环境;
  • MinGW编译器,用以编译C和Fortran语言。
  • Perl编译器,用以编译Perl语言。

从2.2.1节所示链接中下载RTools进行安装,RTools不是R包,不能通过 “install_packages()”的方式安装。

macOS与Linux系统所需内容参考:R包开发-系统设置。

2.3 R包创建流程

2.3.1 命名 | 创建R包

2.3.1.1 R包命名规则

(1)建议

  • 简单易记,易查询
  • 避免大小写同时使用
  • 使用缩略词
  • 使用与R包功能相关词
  • 在单词后面加r
  • R包名需包含函数功能
  • 变量名称和函数名称应该小写,使用下划线进行分割;变量名通常是名词,函数名是动词

(2)要求

  • 只能包含字母,数字及英文点号
  • 字母开头
  • 不能以点号结尾,要以.R结尾

2.3.1.2 R包创建流程

在按照第2.2节配置好工作环境,并成功安装和加载所需R包后,即可创建新的R包,大致流程如下:

  1. 确定R包名,利用 “setwd()” 函数确定R包路径
  2. 编写.r函数源代码,保存为 .R格式的R包函数脚本(“R” 文件夹)
  3. 利用 “devtools” ,生成R包的DESCRIPTION 文件,简单描述R包
  4. 利用 “devtools” ,生成R包的 .Rd 帮助文件(存于2.1节介绍的 “man” 文件夹)
  5. 利用 “testthat” ,测试R包函数脚本(“tests” 文件夹)
  6. 利用 “vignettes” ,编写R包的详细说明文档(“vignettes” 文件夹)
  7. 利用 “build” ,生成R包并发布至github

参考:R packages。

2.3.2 利用 “devtools+Rstudio” 开发R包

2.3.2.1 新建项目(package name | 工作路径)

(1)按R自带流程新建R包

按照 “File——New Project——New Directory——R Package” 的顺序打开R包创建窗口,命名并选择路径后,点击 “Create Project ”。
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第2张图片
图2 创建R Project

创建R包后,可以看到包含了设置的工作路径及R script脚本代码,在工作路径下包含有必须的 “DESCRIPTION” "NAMESPACE"文件及 "R"文件夹

注:

  1. “Ctrl+Shift+N” 可新建一个R Script。
  2. 新建脚本后,先 “CTRL+S” 保存,防止代码丢失。

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第3张图片
图3 R包内容展示

其中,“R” 文件夹下为 .R包源代码,“man” 文件夹下为 .Rd格式的说明文档
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第4张图片

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第5张图片
图4 新建R包架构展示

注:从上图4中可以看到R包路径名称为 “HelloWorld.R”,与图2中输入一致,此处无需.R,注意此处。

R Project创建R包优点:

  1. 分隔不同的项目,避免所有文件在一个文件夹下导致混乱
  2. 使用相对路径读取和写出文件,只需将建立的“HelloWorld.R”文件夹(包含源代码、数据等信息)整体分享运行即可

(2)利用 devtools 新建R包

运行以下代码设定路径:

# 确定路径为F:/R_Iris/_R_packages
setwd("F:/R_Iris/_R_packages")

运行以下代码进行R包创建,可以看到R包架构的输出信息,包括:
路径(Creating)、包名(package)、版本(Version)、DESCRIPTION、NAMESPACE等。

# 确定R包名字为hello
devtools::create('F:/R_Iris/_R_packages/hello')Creating 'F:/R_Iris/_R_packages/hello/'
√ Setting active project to 'F:/R_Iris/_R_packages/hello'
√ Creating 'R/'Writing 'DESCRIPTION'
Package: hello
Title: What the Package Does (One Line, Title Case)
Version: 0.0.0.9000
Authors@R (parsed):
    * First Last <first.last@example.com> [aut, cre] (YOUR-ORCID-ID)
Description: What the package does (one paragraph).
License: `use_mit_license()`, `use_gpl3_license()` or friends to
    pick a license
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.1.2Writing 'NAMESPACE'
√ Writing 'hello.Rproj'
√ Adding '^hello\\.Rproj$' to '.Rbuildignore'
√ Adding '.Rproj.user' to '.gitignore'
√ Adding '^\\.Rproj\\.user$' to '.Rbuildignore'
√ Setting active project to '<no active project>'

在指定路径下可以看到 devtools 方式新建包所含内容:
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第6张图片
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第7张图片

图5 devtools新建R包架构展示

注:利用 “devtools” 方式新建R包,由于未编写源代码,故R文件夹下为空的,需在后续步骤中编写函数并保存(见2.3.2.3节(2)创建函数文件)。

(3)利用R源代码新建R包

此方法需先建立并保存 .R格式的源代码脚本文件

利用ctrl+shift+N快捷方式新建脚本,输入以下函数,ctrl+S保存为“hello.r”文件。

hello <- function() {
  print("Hello, world!")
}

保存后如图6所示:
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第8张图片
图6 源代码脚本

在脚本文件中输入以下代码创建R包:
name:R包名,此处为 “hello”;
code_files:R源代码脚本文件的工作目录路径,此处会在对应路径下新建 “hello1”的文件夹,包含R包(hello)架构内容。

# 创建R包,生成DESCRIPTION及man文件夹
package.skeleton(name="hello1",code_files = "F:/R_Iris/_R_packages/hello.r")

Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Copying code files ...
Making help files ...
Done.
Further steps are described in './hello1/Read-and-delete-me'.

利用源代码文件及 package.skeleton() 函数创建的R包架构内容如图7所示,包括:
DESCRIPTION、NAMESPACE、Read-and-delete-me、man及R文件夹。

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第9张图片
图7 package.skeleton() 新建R包架构展示

2.3.2.2 编写 DESCRIPTION | file.edit()

根据2.3.2.1节可知,介绍了三种R包创建的方式,后续内容以 第二种(devtools) 为主进行后续介绍。

(1)记事本编辑

由图8所示,使用记事本打开其中的 “DESCRIPTION” 文件,按照2.1节描述内容对其进行编写。
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第10张图片
图8 打开DESCRIPTION文件

DESCRIPTION内容修改:
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第11张图片
图9 DESCRIPTION内容修改

(2)R中编辑

利用 file.edit() 函数编写DESCRIPTION

file.edit("DESCRIPTION")

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第12张图片
图10 file.edit() 修改DESCRIPTION

注:看到有文章说这一步一定要用 函数file.edit() 来修改DESCRIPTION文件!!否则封包的时候会报错!!!

DESCRIPTION内容详解:R 包开发。

2.3.2.3 添加R包内置数据文件及函数 | usethis::use_data( ) (开发R包核心)

(1)添加R包内置数据(根据个人需要和目的,可不添加)

对于新建R包,后续测试及他人使用时,通常需要一些测试文件,便于测试和学习。具体步骤为

  • 新建数据文件;
# 新建数据
cities = c('Henan', 'Shenyang', 'Guangzhou')
  • 利用 use_data() 函数将新建数据添加到 hello R包中,加载该R包时,数据会自动加载进来供直接使用。
# 将数据加入R"hello"
setwd("F:/R_Iris/_R_packages/hello")
usethis::use_data(cities)Creating 'data/'Saving 'cities' to 'data/cities.rda'
* Document your data (see 'https://r-pkgs.org/data.html')

运行以上代码后,便会在hello包路径下,自动添加 “data” 文件夹,并将上述新建的数据保存为 "cities.rda"格式。
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第13张图片
图11 R包新增数据

报错1use_data() 原本是 devtools 的功能,但现在为 usethis 的一部分,故使用以下代码会报错。

devtools::use_data(Cities, hello)

Error: 'use_data'不是'namespace:devtools'内的出口对象:

报错2:使用以下代码仍会报错。
解决方式:修改路径 “F:/R_Iris/_R_packages” 到 “F:/R_Iris/_R_packages/hello” 这一层。
解决思路参考:R包制作。

usethis::use_data(cities,hello)

Error: Path 'F:/R_Iris/_R_packages/' does not appear to be inside a project or package.

注:也可现在 "hello" 文件夹下新建 “data” 文件夹,再利用 “save()” 保存数据至 “data” 文件夹,可参考:R包开发的标准姿势,此处不再赘述。

(2)创建函数文件

函数文件是实现特定功能的关键,每个函数文件对应的 .Rd帮助文档 均可以利用 roxygen2包 自动生成,参见2.3.2.4节

  • 函数编写注释
    在RStudio中使用Ctrl+Shift+Alt+R快捷键(光标放在创建的.R文件上),会自动在原文件中生成一些注释信息
    全面的“函数注释”可以包含以下内容,可以直接复制粘贴到自己的.R脚本文件中进行编写使用:
#' @title Dynamic knapsack.
#' @description Creating dynamic algorithm to solve knapsack problem.
#' @details Input takes a data.frame x with two variables v and w and returns the maximum knapsack value and which elements (rows in the data.frame).
#' @param x A a data.frame x with two variables v and w.
#' @param W The knapsack size.
#' @return A list with the maximum knapsack value and which elements.
#' @export
#' @import
#' @importFrom
#' @examples 

详解解释可参考:
R包编写详细教程
如何创建一个R包
R包制作

  • 函数示例
    利用 ctrl+shift+N 新建脚本后,输入以下代码并保存,会自动在 《2.3.2.1 新建项目(package name | 工作路径)》(2)利用 devtools 新建R包 所示路径下保存为 同名hello_city.R的源代码文件,如图12所示。
#' Hello City

#' @param cities string vertices containing cities.
#' @examples
#' hello_city(cities)
#' @export
hello_city <- function(cities) {
    hellos = paste('Hello',cities)
    for (i in hellos ){
        print(i)
    }
}

以上代码中,先在R函数文件内代码上方以 #‘ 开头加入各种roxygen2包相关函数即可。

即先利用 roxygen2 “#” 对源文件添加注释:
第一行表示标题,@param表示输入参数,@examples表示例子,@export表示该函数可被外部调用。
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第14张图片
图12 保存.R函数文件

注:

  • “R” 源代码文件夹下可以包含多个文件;
  • 此处的 example 需谨慎添加,如果不能成功运行内置函数,在 第2.3.2.7节进行 R包系统检查 check() 时会报错。

2.3.2.4 编写R包函数说明文档 DOCUMENT | devtools::document()

根据2.3.2.3函数示例,在对源文件添加注释,编写完具有特定函数功能的源代码文件后,利用 “devtools::document()” 可以自动生成对应的DOCUMENT说明文件。

devtools::document()

i Updating hello documentation
i Loading hello
Writing NAMESPACE
Writing NAMESPACE
Writing hello_city.Rd

通过以上运行结果可以看到:

  • 会自动更新 “NAMESPACE” 文件;
  • 在 R包 “hello” 路径下自动生成 “man” 文件夹
  • 生成 “hello_city.Rd” 函数的说明文档

故每次更新了.R函数文件后,都要运行这个代码更新.Rd文件。
R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第15张图片
图13 .Rd帮助文档DOCUMENT

即再调用R包 “hello” 时,可通过 ?hello_city 查询该函数的说明文档。

?hello_city

i Rendering development documentation for "hello_city"

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第16张图片
图14 调用 hello_city() 函数帮助文档

2.3.2.5 R包测试 | testthat

主要检查 R code的bug问题。

(1)函数测试

运行以下代码便可对 2.3.2.3 节创建函数进行测试,并查看输出结果:

hello_city(cities)

[1] "Hello Henan"
[1] "Hello Shenyang"
[1] "Hello Guangzhou"

(2)单元测试(根据个人需要和目的,可不添加)

首先运行 “usethis::use_testthat()” 函数创建test,见图15:

  • 会自动在 “hello” 文件夹下创建 “tests” 文件夹
  • DESCRIPTION文件中补全suggests信息
  • 创建 ./test/testthat.R 测试脚本,不要人为修改此文件,可在“R CMD check” 及"devtools::check()"时被调用,见2.3.2.7节。

需编写单元测试脚本,保存至创建的 “./test/testthat” 文件夹下,便于后续利用 devtools::test() 运行 test。

usethis::use_testthat()Adding 'testthat' to Suggests field in DESCRIPTION
√ Setting Config/testthat/edition field in DESCRIPTION to '3'Creating 'tests/testthat/'
√ Writing 'tests/testthat.R'
* Call `use_test()` to initialize a basic test file and open it for editing.

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第17张图片
图15 创建单元测试内容

按照上述描述创建 test 后,在 Rsudio 中,利用 devtools::test() 或 Ctrl/Cmd + Shift + T运行 test:

devtools::test()

i Loading hello
i Testing hello
Error in `test_dir()`:
! No test files found
Run `rlang::last_error()` to see where the error occurred.

从图15可以看到创建的 “./test/testthat” 文件夹下显示空白,运行 test 时会报错 “Error in ‘test_dir()’

故单元测试需同时满足以下条件:

  • testthat 测试文件必须存在于 .tests/testthat/ 下
  • 文件名必须以 test 开头

将以test开头命名的 test文件放于"./test/testthat" 文件夹下后(见图16),再次运行 test,单元测试结果正常:

devtools::test()

i Loading hello
i Testing hello
√ | F W S  OK | Context
/ |         0 | hello_city                                                                                                            
== Results ===========================================================================================================================
[ FAIL 0 | WARN 0 | SKIP 0 | PASS 0 ]

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第18张图片
图16 testthat单元测试文件

参考:testthat函数。

2.3.2.6 生成项目说明文档 | usethis::use_vignette()

每一个新建的项目(R包)都会有一个完整的说明文档,用来对该R包进行详细说明解释。

运行usethis::use_vignette(" "),见图17:

  • 可创建一个 rmarkdown文档进行内容编写;
  • “hello” 文件夹下创建 “./vignettes” 说明文档目录
  • 向DESCRIPTION文件中添加必要的依赖项,即Suggests和VignetteBuilder字段
usethis::use_vignette("hello-tutorial")Adding 'knitr' to Suggests field in DESCRIPTION
√ Setting VignetteBuilder field in DESCRIPTION to 'knitr'Adding 'inst/doc' to '.gitignore'
√ Creating 'vignettes/'
√ Adding '*.html', '*.R' to 'vignettes/.gitignore'
√ Adding 'rmarkdown' to Suggests field in DESCRIPTION
√ Writing 'vignettes/hello-tutorial.Rmd'
* Modify 'vignettes/hello-tutorial.Rmd'

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第19张图片
图17 项目说明文档

2.3.2.7 检查R包 | devtools::check()

(1)R包检查内容及结果解读

“2.3.2.5节单元测试” 相比,此处R包检查会对前面创建的 “DESCRIPTION、metadata、NAMESPACE、.R code、data、DOCUMENTATION、tests、vignettes” 等均进行检查。

全绿则代表检查结果无误,其他主要的三种返回检查结果:

  • warning” 问题不大,但如果打算提交给 CRAN,必须解决的潜在问题;
  • notes” 问题不大,但如果打算提交给 CRAN,应该努力消除所有的 notes,即使是假阳性的结果;
  • errors” 问题较大,一般出在函数的 bug 上,跟着系统提示修改 bug直到无 errors。

另外,运行 “check()” 的同时,未通过单元测试的错误一样会显示出来。

有时可能会遇到一个问题,用 “devtools::test()” 运行时测试通过,但在 R CMD check " 时失败。这通常是由于您对测试环境做出了错误的假设,而且通常很难弄清楚

(2)R包检查
在最终创建 R包前,尤其是要发布在 CRAN 上时,需对 R包进行检查,可以利用 "R CMD check"在命令行完成

但在Rstudio中建议利用devtools::check() 或 Ctrl/Cmd + Shift + E检查R包:

devtools::check()

i Updating hello documentation
i Loading hello
Writing NAMESPACE
Writing NAMESPACE
-- Building ----------------------------------------------------------------------------------------------------------------- hello --
Setting env vars:
* CFLAGS    : -Wall -pedantic
* CXXFLAGS  : -Wall -pedantic
* CXX11FLAGS: -Wall -pedantic
* CXX14FLAGS: -Wall -pedantic
* CXX17FLAGS: -Wall -pedantic
* CXX20FLAGS: -Wall -pedantic
--------------------------------------------------------------------------------------------------------------------------------------
√  checking for file 'F:\R_Iris\_R_packages\hello/DESCRIPTION' (522ms)
-  preparing 'hello':
√  checking DESCRIPTION meta-information ... 
-  installing the package to build vignettes
√  creating vignettes (5.9s)
-  checking for LF line-endings in source and make files and shell scripts
-  checking for empty or unneeded directories
-  building 'hello_0.1.tar.gz'
   
-- Checking ----------------------------------------------------------------------------------------------------------------- hello --
Setting env vars:
* _R_CHECK_CRAN_INCOMING_REMOTE_: FALSE
* _R_CHECK_CRAN_INCOMING_       : FALSE
* _R_CHECK_FORCE_SUGGESTS_      : FALSE
* NOT_CRAN                      : true
-- R CMD check -----------------------------------------------------------------------------------------------------------------------
-  using log directory 'C:/Users/赵佳慧/AppData/Local/Temp/RtmpYhOYiq/hello.Rcheck' (481ms)
-  using R version 4.0.5 (2021-03-31)
-  using platform: x86_64-w64-mingw32 (64-bit)
-  using session charset: CP936
-  using options '--no-manual --as-cran'
√  checking for file 'hello/DESCRIPTION' ... 
-  this is package 'hello' version '0.1'
-  package encoding: UTF-8
√  checking package namespace information
√  checking package dependencies (4s)
√  checking if this is a source package ... 
√  checking if there is a namespace
√  checking for executable files (583ms)
√  checking for hidden files and directories ... 
√  checking for portable file names ... 
√  checking serialization versions
   Error in utils::shortPathName(pkgdir) : 
     '<a7>/<41>ppData/Local/Temp/RTMPYH~1/HELLO~1.RCH/00_PKG~1/hello'多字节字符串有错
   停止执行
   
-- R CMD check results ------------------------------------------------------------------------------------------------ hello 0.1 ----
Duration: 9s

0 errors √ | 0 warnings √ | 0 notes √

在上述 “**devtools::check() 检查结果中,报错 “Error in utils::shortPathName(pkgdir)”

报错原因:中文路径?

解决方法:具体的报错原因暂未找出,但其 "--------R CMD check results--------"结果中显示 “0 errors √ | 0 warnings √ | 0 notes √”,故暂时未继续解决该报错,直接进行2.3.2.8节的R包创建。

注:此步经常需要反复操作,直到无 error 为止。

(3)R包全面检查

当然,如果此步直接运行 “check()”,则会在检查整个R包的同时,运行单元测试

check()

i Updating hello documentation
i Loading hello
Writing NAMESPACE
Writing NAMESPACE
-- Building ----------------------------------------------------------------------------------------------------------------------------------------- hello --
Setting env vars:
* CFLAGS    : -Wall -pedantic
* CXXFLAGS  : -Wall -pedantic
* CXX11FLAGS: -Wall -pedantic
* CXX14FLAGS: -Wall -pedantic
* CXX17FLAGS: -Wall -pedantic
* CXX20FLAGS: -Wall -pedantic
--------------------------------------------------------------------------------------------------------------------------------------------------------------
√  checking for file 'F:\R_Iris\_R_packages\hello/DESCRIPTION' (343ms)
-  preparing 'hello':
√  checking DESCRIPTION meta-information ... 
-  installing the package to build vignettes
√  creating vignettes (4.7s)
-  checking for LF line-endings in source and make files and shell scripts
-  checking for empty or unneeded directories
-  building 'hello_0.1.tar.gz'
   
-- Checking ----------------------------------------------------------------------------------------------------------------------------------------- hello --
Setting env vars:
* _R_CHECK_CRAN_INCOMING_REMOTE_: FALSE
* _R_CHECK_CRAN_INCOMING_       : FALSE
* _R_CHECK_FORCE_SUGGESTS_      : FALSE
* NOT_CRAN                      : true
-- R CMD check -----------------------------------------------------------------------------------------------------------------------------------------------
-  using log directory 'C:/Users/赵佳慧/AppData/Local/Temp/RtmpYhOYiq/hello.Rcheck' (381ms)
-  using R version 4.0.5 (2021-03-31)
-  using platform: x86_64-w64-mingw32 (64-bit)
-  using session charset: CP936
-  using options '--no-manual --as-cran'
√  checking for file 'hello/DESCRIPTION' ...
-  this is package 'hello' version '0.1'
-  package encoding: UTF-8
√  checking package namespace information ...
√  checking package dependencies (4s)
√  checking if this is a source package ... 
√  checking if there is a namespace
√  checking for executable files (451ms)
√  checking for hidden files and directories ...
√  checking for portable file names ... 
√  checking serialization versions ... 
   Error in utils::shortPathName(pkgdir) : 
     '<a7>/<41>ppData/Local/Temp/RTMPYH~1/HELLO~1.RCH/00_PKG~1/hello'多字节字符串有错
   停止执行
   
-- R CMD check results ------------------------------------------------------------------------------------------------------------------------ hello 0.1 ----
Duration: 6s

0 errors √ | 0 warnings √ | 0 notes √

(2)R包检查运行结果及报错结果一致。故在解决报错问题后,只运行了(2)R包检查

参考:testthat函数
详细检查参数解释:Automated checking
如何创建一个R包
R包编写详细教程

2.3.2.8 生成R包 | devtools::build()

(1)build R
经过前面的 R包检查后,当无 error 报错时,利用 “devtools::build()” 创建包:

devtools::build()

√  checking for file 'F:\R_Iris\_R_packages\hello/DESCRIPTION' (556ms)
-  preparing 'hello':
√  checking DESCRIPTION meta-information ... 
-  installing the package to build vignettes
√  creating vignettes (3.6s)
-  checking for LF line-endings in source and make files and shell scripts
-  checking for empty or unneeded directories
-  building 'hello_0.1.tar.gz'
   
[1] "F:/R_Iris/_R_packages/hello_0.1.tar.gz"

在第2.3.2.2节(2)R中编辑中修改了R version = 0.1。

故在设定路径下生成一个tar.gz的压缩包文件 “hello_0.1.tar.gz”,这跟平时我们从网上下载的R包是一样的,可以用来 "本地R包安装、?hello查询R包"等操作。见图18:

  • 命名:hello_0.1.tar.gz
  • 保存路径:F:/R_Iris/_R_packages/

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第20张图片
图18 build R package

(2)install R

利用 “devtools::install()” 安装包,见图19:

devtools::install()

√  checking for file 'F:\R_Iris\_R_packages\hello/DESCRIPTION' (351ms)
-  preparing 'hello':
√  checking DESCRIPTION meta-information ... 
-  checking for LF line-endings in source and make files and shell scripts
-  checking for empty or unneeded directories
-  building 'hello_0.1.tar.gz'
   
Running "C:/R/R-40~1.5/bin/x64/Rcmd.exe" INSTALL \
  "C:\Users\***\AppData\Local\Temp\RtmpYhOYiq/hello_0.1.tar.gz" --install-tests 
* installing to library 'C:/R/R-4.0.5/library'
* installing *source* package 'hello' ...
** using staged installation
** R
** data
*** moving datasets to lazyload DB
** tests
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
  converting help for package 'hello'
    finding HTML links ... 好了
    hello_city                              html  
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (hello)

Attaching package: ‘hello’

The following object is masked _by_ ‘.GlobalEnv’:

    cities

R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)_第21张图片
图19 install R package

(3)build vignettes文档

在2.3.2.6节 生成项目文档(vignettes)中创建了一个 rmarkdown文档进行内容编写,此处未对R包内容进行详细编写,仅为示例。

若为了使用browseVignettes() 查看创建的 vignettes 项目说明文档,需要 build vignettes:

devtools::build_vignettes()
devtools::build_manual(pkg = ".", path = './doc')
devtools::build(vignettes = TRUE, manual = TRUE)

安装代码:

devtools::install(build_vignettes = TRUE)

查看vignettes 项目说明文档:

browseVignettes(RPkgName)

R包编写详细教程:vignettes

2.3.2.9 发布R包 | devtools::build()

通常R包可发布在 CRAN 或 github 上:

  • CRAN需要严苛的R包检查,满足特定规范,并且需要定期维护;
  • github通常没有此限制,故自用R包优先选择发布在 github上。

R包发布的具体流程可参考:R包编写详细教程。

2.4 总结

  • 至此,已完成R包创建的整个流程,主要是为了了解一个 R包所含的内容,为学习其他 R包提供思路和辅助;
  • 此文只是以 R默认生成的 hello代码作为示例来完成的;后续若要建立具有特定功能的R包,还需要注重R函数的编写。

你可能感兴趣的:(R,r语言,开发语言)