如何在roxygen2的@examples中运行文档函数且不使用已弃用功能?
问题描述
我有多个相似函数,文档仅需修改少量内容。为减少重复,我在文档中调用函数生成内容,该方式在roxygen2的@description和@param中有效,但@examples中的内联代码无法被执行。
示例代码如下:
useless_description <- function(name) { paste0('This useless function prints the word "', name , '" n times.') } useless_example <- function(name) { paste("# Print ", name, " 1 time", name, "(1)", "", "# Print ", name, " 3 times", name, "(3)", sep = "\n" ) } #' @title Hello #' @description `r useless_description("hello")` #' @examples `r useless_example("hello")` hello <- function(n) { print(rep("hello", n)) } #' @title Goodbye #' @description `r useless_description("goodbye")` #' @examples `r useless_example("hello")` goodbye <- function(n) { print(rep("goodbye", n)) }
运行devtools::document()后,hello()函数的帮助页中@examples内联代码未被解析。我找到使用已弃用关键字@eval的解决方案,但希望了解是否存在无需使用已弃用函数的实现方式。
可行解决方案
方案1:利用roxygen2模板机制
roxygen2支持通过模板复用示例代码,步骤如下:
- 创建模板文件(比如
inst/templates/useless_example_template.R),内容为:
# Print {{name}} 1 time {{name}}(1) # Print {{name}} 3 times {{name}}(3)
- 在函数文档中用
roxygen2::template()引入模板并传入参数:
#' @title Hello #' @description `r useless_description("hello")` #' @examples #' `r roxygen2::template("useless_example_template.R", data = list(name = "hello"))` hello <- function(n) { print(rep("hello", n)) } #' @title Goodbye #' @description `r useless_description("goodbye")` #' @examples #' `r roxygen2::template("useless_example_template.R", data = list(name = "goodbye"))` goodbye <- function(n) { print(rep("goodbye", n)) }
方案2:自定义roxygen2标签
通过自定义标签来处理示例生成逻辑:
- 在包的
R/zzz.R中添加标签注册代码:
.onLoad <- function(libname, pkgname) { roxygen2::register_tag("useless_examples", function(x) { name <- x[[1]] example_text <- useless_example(name) roxygen2::block("examples", example_text) }) }
- 在函数文档中使用自定义标签:
#' @title Hello #' @description `r useless_description("hello")` #' @useless_examples "hello" hello <- function(n) { print(rep("hello", n)) } #' @title Goodbye #' @description `r useless_description("goodbye")` #' @useless_examples "goodbye" goodbye <- function(n) { print(rep("goodbye", n)) }
方案3:用glue实现字符串插值
借助glue包的插值功能,直接在@examples中生成代码:
- 确保包依赖
glue,修改示例生成函数:
library(glue) useless_example <- function(name) { glue(' # Print {name} 1 time {name}(1) # Print {name} 3 times {name}(3) ') }
- 在文档中用大括号包裹表达式:
#' @title Hello #' @description `r useless_description("hello")` #' @examples #' {useless_example("hello")} hello <- function(n) { print(rep("hello", n)) } #' @title Goodbye #' @description `r useless_description("goodbye")` #' @examples #' {useless_example("goodbye")} goodbye <- function(n) { print(rep("goodbye", n)) }
roxygen2会解析大括号内的表达式,将生成的文本替换到@examples块中。
内容的提问来源于stack exchange,提问作者Johan Ejstrud
相关产品推荐
相关产品推荐

