如何记录依赖于外部包 类 的 S4 方法?

How to document S4 methods that rely on classes from external packages?

我正在努力寻找正确的方法来记录作用于外部包中 classes 的 S4 方法。免责声明:总的来说,我对 S4 和 OOP 还很陌生。

假设我有以下带有 roxygen 注释的泛型:

#' Converting an object to a polygon data.frame
#'
#' @param object some description
#' @param selection some description
#'
#' @details This function tries to parameterise polygons.
#' @return A data.frame
#' @export
#' @examples
#' x <- S4Vectors::Rle(rep(1:5, each = 5))
#' to_poly(x)
setGeneric("to_poly", function(object, selection) standardGeneric("to_poly"))

我已经为 S4Vectors 包中的 class Rle(在 bioconductor 上)编写了以下方法。这些 Rle 的功能与 base::rle 的功能类似,但有一些额外的便利功能。

#' @rdname to_poly
setMethod(
  "to_poly",
  signature(object = "Rle", selection = "missing"),
  function(object) {
    requireNamespace("S4Vectors", quietly = TRUE)
    df <- data.frame(
      x = c(1, base::rbind(start(object), end(object)), length(object)),
      y = c(0, base::rbind(runValue(object), runValue(object)), 0)
    )
    df[!duplicated(df),]
  }
)

现在我使用 requireNamespace 而不是在顶部添加 #' importFrom S4Vectors Rle 的原因是我不希望人们在安装软件包时被迫下载 S4Vectors。我仍然希望这种方法与 base::rle.

的类似方法一起存在

然而,当我 运行 devtools::document(roclets = c('rd', 'collate', 'namespace')) 使用 roxygen2 记录以上内容时,我收到以下警告:

in method for ‘to_poly’ with signature ‘object="Rle",selection="missing"’: no definition for class “Rle”

很明显,这似乎是一种次优的记录方式,因为 #' importFrom S4Vectors Rle 方法工作正常,但这会成为我不热衷的依赖项(我认为)。

记录此方法的最佳方式是什么,它不会让 roxygen2 抛出错误并且不会强制用户安装 S4Vectors?

我会回答我自己的问题,以便将来有人可能遇到同样的问题。

我不知道这是否是最好的方法,但我在 ?signature-class 中找到了一些提示。

简而言之,在保存 class 名称 (.Data) 和参数名称 (names) 的插槽旁边,签名 class 对象还有一个package 插槽。这个特定的插槽不是 signature() 的正式参数,也不是构造函数 new("signature", functionDef, ...).

的正式参数

解决这个问题的方法是手动构建一个 structure 并将结构传递给 as(..., "signature")。文档没有给出任何错误,功能仍然有效,我不需要导入字段中的包名称。

setMethod(
  "to_poly",
  as(structure(.Data = c("Rle", "missing"),
               names = c("object", "selection"),
               package = c("S4Vectors", "")),
     "signature"),
  function(object) {
    requireNamespace("S4Vectors", quietly = TRUE)
    df <- data.frame(
      x = c(1, base::rbind(start(object), end(object)), length(object)),
      y = c(0, base::rbind(runValue(object), runValue(object)), 0)
    )
    df[!duplicated(df),]
  }
)