【问题标题】:S3methods in NAMESPACE not exportedNAMESPACE 中的 S3 方法未导出
【发布时间】:2018-04-08 12:51:10
【问题描述】:

我正在使用 devtools::document() 开发一个 R 包来创建 NAMESPACE 文件。其中几个函数是用于汇总、预测、绘图、打印的 S3 方法,其中泛型位于 basestats 中。 我正在按照 Hadley 的建议使用 @export,这会导致 NAMESPACE 中的 S3method 条目正确,并且包通过了所有检查 -as-cran。但是,函数不会在 NAMESPACE 中导出,因此找不到调用 print.myclass(我知道这是避免混淆 NAMESPACE 的理想行为)。但是,通过 Mypackage::print.myclass 调用该函数也会导致该函数不是从Mypackage 导出的对象的错误。

问题:这是正确的行为吗?或者是否需要其他步骤才能导出功能?我尝试同时添加@method print Myclass 和@export,但没有成功。在 MAC OS X 10.12.6 下使用 R 3.4.2 和 devtools 1.13.3

谢谢!梅丽丝

已编辑:更新为添加/导出方法和导出函数的代码

简单示例 - 在 RStudio 中构建具有功能的骨架包:

#' test for export of S3 methods
#'
#' @title "print hello world for any object"
#' @param x object
#' @param digits optional number specifying the number of digits to display
#' @param ... other parameters to be passed to \code{print.default}
#' @export print.hello
#' @export
print.hello = function (x, digits = max(3, getOption("digits") - 3), ...)
{
  cat("\n Hello World \n")
  invisible()
}

命名空间现在有

# Generated by roxygen2: do not edit by hand

S3method(print,hello)
export(print.hello)

使用不带参数的@export 会导出方法,而@export print.hello 会导出函数,但不会将方法添加到NAMESPACE(这会导致包检查出错)。两者都允许导出方法和函数。

【问题讨论】:

  • 问题:这是正确的行为吗?我认为这是正确的行为。

标签: r namespaces devtools


【解决方案1】:

首先,为了正式定义一个S3方法,并在不手动更改命名空间文件的情况下正确导出(假设你使用的是roxygen),

#' test for export of S3 methods
#'
#' @title "print hello world for any object"
#' @param x object
#' @param digits optional number specifying the number of digits to display
#' @param ... other parameters to be passed to \code{print.default}
#'
#' @rdname print
#' @export print
print <- function(x, ...){
  UseMethod("print")
}

#' @rdname print
#' @export print.hello
#' @export
print.hello <- function (x, digits = max(3, getOption("digits") - 3), ...)
{
  cat("\n Hello World \n")
  invisible()
}

这或多或少为您提供了testPackage::print.hello 的预期行为。这里更重要的是要了解 S3 方法的确切用途。它用于 R 中的方法调度,. 之后的后缀应始终代表您应该作为函数的第一个参数放入的对象类。也就是说,在这种情况下,如果你想使用print.helloprint 的单个调用,你必须放置一个hello 的类,在你成功构建和加载testpackage 后尝试下面的示例

a = 1
print(a) # method dispatched as print.default because class of a is numeric
# 1  
class(a) <- 'hello'
print(a) # method dispatched as print.hello
# Hello World 

【讨论】:

  • 这是在定义你自己的print 泛型函数,这不是你想要的。只需从此代码中删除 print 的定义即可。
  • 谢谢!我不想从基础 R 重新定义泛型,因此 Luke 的建议有效(保留两个 @export 语句将允许我定义 S3 方法并将其导出用于选择函数)使用 roxygen 而无需手动编辑 NAMESPACE。
  • 补充答案:您可以在“专业导出”部分下的 vignette file 中找到所有可能的 @export 语法变体的文档
【解决方案2】:

这是您的NAMESPACE 文件的正确行为。 :: 访问 exported 变量,因此 testPackage::print.hello 应该会失败。 ::: 访问 internal 变量,所以 testPackage:::print.hello 应该适合你。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    相关资源
    最近更新 更多