You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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支持通过模板复用示例代码,步骤如下:

  1. 创建模板文件(比如inst/templates/useless_example_template.R),内容为:
# Print {{name}} 1 time
{{name}}(1)

# Print {{name}} 3 times
{{name}}(3)
  1. 在函数文档中用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标签

通过自定义标签来处理示例生成逻辑:

  1. 在包的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)
  })
}
  1. 在函数文档中使用自定义标签:
#' @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中生成代码:

  1. 确保包依赖glue,修改示例生成函数:
library(glue)

useless_example <- function(name) {
  glue('
# Print {name} 1 time
{name}(1)

# Print {name} 3 times
{name}(3)
')
}
  1. 在文档中用大括号包裹表达式:
#' @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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:52:39