使用 usethis 和 devtools 组织软件包结构
使用 usethis 辅助工具搭建软件包目录、DESCRIPTION 和 NAMESPACE
使用 usethis 和 devtools 组织软件包结构 是 CoddyKit 上的免费 R Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。
为什么要构建 R 程序包
R 程序包是共享可复用代码、数据和文档的标准方式。即使您从不将程序包发布到 CRAN,将代码打包也能促使您遵循良好实践:为函数编写文档、添加单元测试,并使用清晰的命名空间。devtools 和 usethis 让整个过程变得简单明了。
创建程序包骨架
usethis::create_package('~/mypackage') 会创建一个包含所有必需文件的目录:DESCRIPTION、NAMESPACE 和 R/ 目录。它还会自动在 RStudio 中打开新项目。
# library(usethis)
# library(devtools)
#
# usethis::create_package('~/mypackage')
#
# Creates:
# mypackage/
# DESCRIPTION <- package metadata
# NAMESPACE <- exported symbols (auto-managed by roxygen2)
# R/ <- your R source files
# .Rbuildignore <- files to exclude from package buildsDESCRIPTION 文件
DESCRIPTION 文件是程序包清单。其主要字段包括:
- Title — 单行描述(使用标题格式,不加句号)
- Version — 语义化版本号(例如
0.1.0) - Author / Authors@R — 程序包作者
- Depends — 所需的 R 版本
- Imports — 程序包调用的其他程序包
- License — 例如 MIT、GPL-3
# DESCRIPTION example:
# Package: mypackage
# Title: Tools for Analyzing Survey Data
# Version: 0.1.0
# Authors@R: person('Alice', 'Smith', email='alice@example.com', role=c('aut','cre'))
# Description: Provides helper functions for cleaning and summarizing survey responses.
# Depends: R (>= 4.1.0)
# Imports: dplyr, stringr
# License: MIT + file LICENSE使用 use_r() 添加函数
usethis::use_r('my_function') 会创建 R/my_function.R 并打开该文件进行编辑。R/ 中的每个文件应包含一个函数,或一小组关系密切的函数。不要在程序包文件中使用 source() 调用。
# usethis::use_r('add') # creates R/add.R
#
# Write your function in R/add.R:
# add <- function(x, y) {
# if (!is.numeric(x) || !is.numeric(y)) stop('x and y must be numeric')
# x + y
# }
#
# Then document it with roxygen2 comments above the function.devtools::load_all() — 开发循环
devtools::load_all()(RStudio 中的键盘快捷键为 Ctrl+Shift+L)会模拟安装并加载程序包。它会将 R/ 中的所有文件加载到当前会话中,但不会实际安装程序包。这是迭代开发周期的核心。
# Development loop:
# 1. Edit R/add.R
# 2. devtools::load_all() # Ctrl+Shift+L
# 3. add(2, 3) # test interactively
# 4. Go to step 1
#
# load_all() is much faster than install.packages()
# because it skips compilation and installation steps.devtools::check() — 全面检查
devtools::check()(Ctrl+Shift+E)会运行 R CMD check — CRAN 使用的综合检查套件。它会检查文档、测试、示例、命名空间等内容。请以 0 个 ERROR、0 个 WARNING 以及尽可能少的 NOTE 为目标。
# devtools::check() # runs R CMD check
#
# Common errors to fix:
# ERROR: Undocumented function 'add' => add roxygen2 docs
# WARNING: No NAMESPACE file => run devtools::document()
# NOTE: No examples => add @examples in roxygen2
# NOTE: Dependencies in DESCRIPTION not used => clean up ImportsR/ 目录结构
所有源文件都放在 R/ 中。常见约定包括:
- 每个函数族使用一个文件(例如
R/utils.R、R/plot_helpers.R) - 使用
R/data.R编写数据集文档 - 使用
R/zzz.R存放.onLoad()和.onAttach()钩子
R/ 中不能包含子目录 — 所有文件都应直接位于顶层。
# Typical R/ directory for a small package:
# R/
# add.R <- add() function + documentation
# subtract.R <- subtract() function
# utils.R <- internal helpers (not exported)
# data.R <- documentation for bundled datasets
# package.R <- @docType package documentationman/ 目录
man/ 包含 .Rd 帮助文件,每个导出的函数对应一个文件。您绝不应手动编辑这些文件 — 它们由 devtools::document() 根据 roxygen2 注释生成。请将它们与源代码一起提交。
# man/ is auto-generated:
# man/
# add.Rd <- generated from @title, @param etc. in R/add.R
# subtract.Rd <- generated from R/subtract.R
#
# Regenerate with:
# devtools::document() # also updates NAMESPACE
#
# Never edit .Rd files directly -- changes will be overwritten
cat('Always edit roxygen2 comments, never man/*.Rd files directly
')tests/ 目录
usethis::use_testthat() 会创建 tests/testthat/ 目录,并将 testthat 添加到 DESCRIPTION 中。在该目录内创建名为 test-*.R 的测试文件。使用 devtools::test()(Ctrl+Shift+T)运行所有测试。
# Set up testing:
# usethis::use_testthat()
#
# Creates:
# tests/
# testthat.R <- runner script (do not edit)
# testthat/
# test-add.R <- your test file
#
# Run tests:
# devtools::test()
# devtools::test_file('tests/testthat/test-add.R')正确添加依赖项
绝不要在程序包源文件中使用 library(pkg)。请改用以下方式:
- 使用
usethis::use_package('dplyr')将程序包添加到DESCRIPTION的Imports中 - 使用
pkg::function()调用函数,或在 roxygen2 中添加@importFrom pkg function - 对于仅在示例或测试中需要的程序包,使用
Suggests
# Add a dependency:
# usethis::use_package('stringr') # adds to Imports
# usethis::use_package('ggplot2', 'Suggests') # adds to Suggests
#
# In R/my_function.R:
# clean_names <- function(x) {
# stringr::str_to_lower(stringr::str_trim(x)) # use pkg:: prefix
# }程序包开发工作流总结
R 程序包开发的标准迭代周期如下:
create_package()— 仅创建一次骨架use_r('name')— 创建源文件- 编写函数并为其编写文档(roxygen2)
load_all()— 将程序包加载到会话中,以便交互式测试document()— 重新生成 man/ 和 NAMESPACEtest()— 运行单元测试check()— 执行完整的 R CMD check
快速检查:DESCRIPTION 字段
DESCRIPTION 中的哪个字段列出了您的程序包直接调用的 R 程序包(硬依赖项)?
程序包结构回顾
R 程序包开发中的关键文件和命令:
usethis::create_package()— 创建包含 DESCRIPTION、NAMESPACE 和 R/ 的骨架DESCRIPTION— Title、Version、Imports 和 License 元数据usethis::use_r('name')— 向 R/ 添加源文件devtools::load_all()— 快速迭代式重新加载(Ctrl+Shift+L)devtools::document()— 根据 roxygen2 重新生成 man/devtools::check()— 完整的 R CMD check,目标是 0 个错误和警告- 不要在程序包源代码中放置
library()— 请使用pkg::fn()
常见问题解答
「使用 usethis 和 devtools 组织软件包结构」课时是免费的吗?
是的 — 「使用 usethis 和 devtools 组织软件包结构」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。
「使用 usethis 和 devtools 组织软件包结构」这节课中我会学到什么?
使用 usethis 辅助工具搭建软件包目录、DESCRIPTION 和 NAMESPACE 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 R Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「使用 usethis 和 devtools 组织软件包结构」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 R Academy 课中编写并运行代码吗?
能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 usethis 和 devtools 组织软件包结构
- 使用 roxygen2 编写函数文档
- 使用 testthat 进行单元测试
- CRAN 提交与软件包维护