关于 cran-extrachecks
面向 R 包开发者的 CRAN 提交准备技能,通过系统检查常见审核要求,发现问题并提出修改建议;仅在用户批准后实施更改。
主要功能
- 01按清单检查 CRAN 提交要求
- 02审查 DESCRIPTION 与文档
- 03检查 README、链接和许可
- 04针对发现的问题提出修复方案
- 05经用户批准后修改并复核
适用场景
- 01准备 R 包首次提交 CRAN
- 02处理 CRAN 退回后的重新提交
- 03检查导出函数的文档和示例
- 04排查 URL、README 与包元数据问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ posit-dev/ skills --skill cran-extrachecks安装后在 Claude Code 中输入/cran-extrachecks确认已加载。
详细介绍
CRAN 额外检查
通过系统性检查 CRAN 审核人员会执行、但 devtools::check() 不会捕获的常见临时要求,帮助 R 包开发者为提交到 CRAN 做好准备。
工作流
- 初步评估:询问用户这是首次提交还是重新提交
- 执行标准检查清单:按顺序逐项检查(见下文)
- 找出问题:审查文件时记录具体问题
- 提出修复方案:针对发现的每个问题提出具体修改建议
- 实施修改:仅在用户批准后进行编辑
- 验证:确认所有修改均已完成
CRAN 标准准备检查清单
按顺序逐项检查:
- 创建 NEWS.md:如果文件尚不存在,运行
usethis::use_news_md() - 创建 cran-comments.md:如果文件尚不存在,运行
usethis::use_cran_comments() - 检查 README:
- 确保其中包含在包被 CRAN 接收后仍有效的安装说明(通常为
install.packages("pkgname"))。 - 检查是否包含相对链接。相对链接在 GitHub 上可用,但会被 CRAN 标记。请使用指向包文档的完整 URL,或移除这些链接。
- README 是否清楚地说明了包的用途和功能?
- 重要:如果存在 README.Rmd,只编辑 README.Rmd(README.md 会被覆盖),然后运行
devtools::build_readme()重新生成 README.md
- 确保其中包含在包被 CRAN 接收后仍有效的安装说明(通常为
- 校对 DESCRIPTION:仔细检查
Title:和Description:字段(见下方详细指南) - 检查函数文档:确认所有导出的函数都有
@return和@examples(见下方详细指南) - 确认版权所有者:检查
Authors@R:是否包含角色为[cph]的版权所有者 - 检查打包文件的许可:检查所有包含的第三方文件的许可情况
- 运行 URL 检查:使用
urlchecker::url_check()并修复发现的问题
CRAN 详细检查
文档要求
返回值文档(严格执行)
CRAN 现在严格要求为所有导出的函数提供 @return 文档。使用 roxygen2 标签 @return 说明函数返回的内容。
- 即使函数标记为
@keywords internal,也必须提供 - 即使函数不返回任何内容,也必须提供——可注明
@return None或类似内容 - 每个导出的函数都必须包含此项
示例:
# Missing @return - WILL BE REJECTED
#' Calculate sum
#' @export
my_sum <- function(x, y) {
x + y
}
# Correct - includes @return
#' Calculate sum
#' @param x First number
#' @param y Second number
#' @return A numeric value
#' @export
my_sum <- function(x, y) {
x + y
}
# For functions with no return value
#' Print message
#' @param msg Message to print
#' @return None, called for side effects
#' @export
print_msg <- function(msg) {
cat(msg, "\n")
}
导出函数的示例
如果导出的函数具有有意义的返回值,几乎肯定需要包含 @examples 部分。使用 roxygen2 标签 @examples。
- 即使函数标记为
@keywords internal,也必须提供 - 纯粹用于产生副作用的函数(例如,创建目录)可例外
- 示例必须可执行
未导出函数的示例
如果为未导出的函数编写了 roxygen 示例,必须采取以下任一做法:
- 使用
:::记法调用它们:pkg:::my_fun() - 使用
@noRd标签来阻止创建.Rd文件
谨慎使用 \dontrun{}
只有当示例确实无法执行时(例如,缺少其他软件、API 密钥等),才应使用 \dontrun{}。
- 如果要展示错误,请改用
try()包裹调用 - 可考虑使用自定义谓词(例如,
googlesheets4::sheets_has_token())配合if ()代码块 - 有时可以使用
interactive()作为条件 - 耗时较长(> 5 秒)的示例可使用
\donttest{}
绝不要在示例中注释掉代码
# BAD - Will be rejected
#' @examples
#' # my_function(x) # Don't do this!
CRAN 的指导意见:“示例中的代码行绝不能注释掉。理想情况下,应寻找可定期执行和检查的玩具示例。”
使用建议包保护示例
对于需要建议包的整个示例部分,请使用 @examplesIf:
#' @examplesIf rlang::is_installed("dplyr")
#' library(dplyr)
#' my_data %>% my_function()
对于示例中的单个代码块:
#' @examples
#' if (rlang::is_installed("dplyr")) {
#' library(dplyr)
#' my_data %>% my_function()
#' }
DESCRIPTION Title 字段
CRAN 对 Title 有严格要求:
使用标题式大小写
除 'a'、'the' 等冠词外,所有单词首字母均大写。可使用 tools::toTitleCase() 辅助格式化。
避免冗余
常见会被标记的短语:
- “A Toolkit for” → 删除
- “Tools for” → 删除
- “for R” → 删除
示例:
# BAD
Title: A Toolkit for the Construction of Modeling Packages for R
# GOOD
Title: Construct Modeling Packages
# BAD
Title: Command Argument Parsing for R
# GOOD
Title: Command Argument Parsing
用引号括起软件/程序包名称
所有软件和 R 程序包名称都要用单引号括起:
# GOOD
Title: Interface to 'Tiingo' Stock Price API
长度限制
标题须少于 65 个字符。
DESCRIPTION Description 字段
开头不得使用禁用短语
以以下内容开头的描述会被 CRAN 拒绝:
- “This package”
- 程序包名称
- “Functions for”
# BAD
Description: This package provides functions for rendering slides.
Description: Functions for rendering slides to different formats.
# GOOD
Description: Render slides to different formats including HTML and PDF.
扩展为 3–4 个句子
单句描述不够充分。请更全面地说明:
- 程序包的功能
- 它可能带来的帮助
- 它有助于解决的问题类型
# BAD (too short)
Description: Render slides to different formats.
# GOOD
Description: Render slides to different formats including HTML and PDF.
Supports custom themes and progressive disclosure patterns. Integrates
with 'reveal.js' for interactive presentations. Designed for technical
presentations and teaching materials.
用引号括起软件名称,而非函数名称
# BAD
Description: Uses 'case_when()' to process data.
# GOOD
Description: Uses case_when() to process data with 'dplyr'.
软件、程序包和 API 名称都要用单引号括起(包括 'R')。函数名称不需要。
展开所有首字母缩略词
首次提及时,必须完整写出所有首字母缩略词:
# BAD
Description: Implements X-SAMPA processing.
# GOOD
Description: Implements Extended Speech Assessment Methods Phonetic
Alphabet (X-SAMPA) processing.
仅出版物标题使用双引号
双引号仅用于出版物标题,不要用于短语或强调:
# BAD
Description: Handles dates like "the first Monday of December".
# GOOD
Description: Handles dates like the first Monday of December.
URL 和链接验证
所有 URL 都必须使用 HTTPS
CRAN 要求所有 URL 使用 https:// 协议。HTTP 链接会被拒绝。
# BAD
URL: http://paleobiodb.org/
# GOOD
URL: https://paleobiodb.org/
不要使用会重定向的 URL
CRAN 会拒绝重定向到其他位置的 URL。拒绝示例:
Found the following (possibly) invalid URLs:
URL: https://h3geo.org/docs/core-library/coordsystems#faceijk-coordinates
(moved to https://h3geo.org/docs/core-library/coordsystems/)
使用 urlchecker 程序包
# Find redirecting URLs
urlchecker::url_check()
# Automatically update to final destinations
urlchecker::url_update()
忽略发布后才会生效的 URL
有些目前无法解析的 URL 会在程序包发布到 CRAN 后生效。这些 URL 不应修改:
- CRAN 徽章 URL(例如,
https://cran.r-project.org/package=pkgname) - CRAN 状态徽章(例如,
https://www.r-pkg.org/badges/version/pkgname) - CRAN 检查结果(例如,
https://cranchecks.info/badges/pkgname) - 在发布后部署于 r-universe 或 pkgdown 网站上的程序包文档 URL
如果 urlchecker::url_check() 标记了这些 URL,请保持原样。这些预期 URL 会在程序包发布到 CRAN 后生效。
检查无效的文件 URI
README 中的相对链接在程序包构建后必须仍然有效。常见问题:
Found the following (possibly) invalid file URI:
URI: CODE_OF_CONDUCT.md
From: README.md
当文件位于 .Rbuildignore 中时会出现此问题。解决方法:
- 从
.Rbuildignore中移除该文件 - 使用
usethis::use_code_of_conduct(),它会生成不含相对链接的章节
管理要求
版权持有人角色
即使只有你一位作者,也始终要在 Authors 字段中添加 [cph] 角色:
# Required
Authors@R: person("John", "Doe", role = c("aut", "cre", "cph"))
Posit 支持的程序包
对于位于与 Posit 相关的 GitHub 组织(posit-dev、rstudio、r-lib、tidyverse、tidymodels)中的程序包,或由使用 @posit.co 邮箱地址的人维护的程序包,须将 Posit Software, PBC 列为版权持有人和资助方:
Authors@R: c(
person("Jane", "Doe", role = c("aut", "cre"),
email = "[email protected]"),
person("Posit Software, PBC", role = c("cph", "fnd"),
comment = c(ROR = "03wc8by49"))
)
LICENSE 年份
将 LICENSE 年份更新为当前提交年份:
# If LICENSE shows 2024 but submitting in 2026
# Update: 2024 → 2026
方法参考文献
CRAN 可能会要求:
如果有介绍程序包所用方法的参考文献,请将其添加到 description 字段……
如果没有参考文献,请回复邮件说明这一点。也可以考虑在 cran-comments.md 中提前注明:
## Method References
There are no published references describing the methods in this package.
The package implements original functionality for [brief description].
需要检查的关键文件
按以下顺序系统地检查这些文件:
- DESCRIPTION:Title、Description、Authors@R、URL、许可证年份
- R/*.R:函数文档(
@return、@examples、@examplesIf、@noRd) - README.Rmd(如果存在):编辑此文件(而非 README.md),然后运行
devtools::build_readme() - README.md:检查安装说明、相对链接和 URL。仅当 README.Rmd 不存在时才直接编辑
- cran-comments.md:给审查人员的预先说明
- NEWS.md:此版本的版本说明
- .Rbuildignore:README 中引用的文件
常见修复模式
DESCRIPTION Title:
# Before
Title: A Toolkit for the Construction of Modeling Packages for R
# After
Title: Construct Modeling Packages
DESCRIPTION Description:
# Before
Description: This package provides functions for rendering slides.
# After
Description: Render slides to different formats including HTML and PDF.
Supports custom themes and progressive disclosure. Integrates with
'reveal.js' for interactive presentations.
函数文档:
# Before - Missing @return
#' Calculate total
#' @param x Values
#' @export
calc_total <- function(x) sum(x)
# After - Complete documentation
#' Calculate total
#' @param x Numeric values to sum
#' @return A numeric value representing the sum
#' @examples
#' calc_total(1:10)
#' @export
calc_total <- function(x) sum(x)
实用工具
tools::toTitleCase()- 使用正确的大小写格式化标题urlchecker::url_check()- 查找有问题的 URLurlchecker::url_update()- 修复会重定向的 URLusethis::use_news_md()- 创建 NEWS.mdusethis::use_cran_comments()- 创建 cran-comments.mddevtools::build_readme()- 从 README.Rmd 重新生成 README.mdusethis::use_code_of_conduct()- 添加行为准则,且不使用相对链接usethis::use_build_ignore()- 在 R 包构建中忽略文件usethis::use_package()- 将包依赖项添加到 DESCRIPTIONusethis::use_tidy_description()- 整理 DESCRIPTION 的格式
最终验证清单
提交前使用此清单,确保没有遗漏:
文件和结构
-
NEWS.md存在,并记录了此版本的变更 -
cran-comments.md存在,并包含提交说明 - 如果存在 README.Rmd,则编辑的是该文件(而不是 README.md),并运行了
devtools::build_readme() - README 包含有效的安装说明(
install.packages("pkgname")) - README 不含相对链接(所有链接都是完整 URL 或已移除)
DESCRIPTION 文件
-
Title:使用标题格式 -
Title:不含多余短语(“A Toolkit for”、“Tools for”、“for R”) -
Title:中所有软件/包名称都使用单引号括起 -
Title:少于 65 个字符 -
Description:不以“This package”、包名称或“Functions for”开头 -
Description:使用 3-4 个句子说明用途和实用价值 -
Description:中的软件/包/API 名称(包括 'R')都使用引号括起,但函数名称除外 -
Description:在首次提及时展开所有首字母缩略词 -
Description:仅对出版物标题使用双引号 -
Authors@R:包含具有[cph]角色的版权持有者 - 对于 Posit 包:包含
person("Posit Software, PBC", role = c("cph", "fnd"), comment = c(ROR = "03wc8by49")) - LICENSE 年份与当前提交年份一致
函数文档
- 所有导出的函数都有
@return文档 - 所有具有有意义返回值的导出函数都有
@examples - 示例部分均未使用注释掉的代码
- 示例避免使用
\dontrun{},除非确有必要 - 需要建议包的示例使用
@examplesIf或if保护 - 包含示例的未导出函数使用
:::记法或@noRd
URL 和链接
- 已运行
urlchecker::url_check() - 所有 URL 均使用 https 协议(不含 http 链接)
- 不含会重定向的 URL(CRAN 预期徽章 URL 除外)
- 预期 URL(如 CRAN 徽章等)保持原样
- README 中没有引用
.Rbuildignore文件的相对链接
可选但建议
- 如果担心方法引用问题,已在
cran-comments.md中添加预先说明 - 如果包含第三方文件,已审查随附文件的许可