gpt4 book ai didi

r - 在不引入依赖关系的情况下,在 R 包中定义 S3 方法的首选方法是什么?

转载 作者:行者123 更新时间:2023-12-03 15:54:54 28 4
gpt4 key购买 nike

我有一个 R 包(目前不在 CRAN 上),它定义了来自其他包(特别是 knitr::knit_printhuxtable::as_huxtable )的几个通用函数的 S3 方法。但是,它们不是我的包的关键部分,所以我不想在用户安装我的包时创建对这些包的依赖。在 R 4.0.0 之前,我导出了 S3 方法而不导入泛型。使用 roxygen2 , 我的 @export指令被翻译成 export() NAMESPACE 中的指令而不是 S3method() .这在 R 版本 < 4.0.0 中运行良好,因为 R 在全局环境中查找匹配 generic_function.class方法,而不是依赖于 S3 方法的正确注册。但是,根据 this blog on developer.r-project.org , R 不再寻找未注册的 S3 方法。

最好的方法是什么?现在,我添加了 @importFrom给我的指令 roxygen2块并将这两个包添加到说明的导入部分。但是,据我所知,这意味着安装我的软件包的任何用户也必须安装 knitrhuxtable不管他们是否愿意。

最佳答案

幸运的是,对于 R >= 3.6.0,你甚至不需要 the answer by caldwellst .从您上面链接的博客条目中:

Since R 3.6.0, S3method() directives in NAMESPACE can also be used to perform delayed S3 method registration. With S3method(PKG::GEN, CLS, FUN) function FUN will get registered as an S3 method for class CLS and generic GEN from package PKG only when the namespace of PKG is loaded. This can be employed to deal with situations where the method is not “immediately” needed, and having to pre-load the namespace of pkg (and all its strong dependencies) in order to perform immediate registration is considered too “costly”.



此外,这也在文档中针对 vctrs::s3_register() 的其他建议进行了讨论。 :
#' For R 3.5.0 and later, `s3_register()` is also useful when demonstrating
#' class creation in a vignette, since method lookup no longer always involves
#' the lexical scope. For R 3.6.0 and later, you can achieve a similar effect
#' by using "delayed method registration", i.e. placing the following in your
#' `NAMESPACE` file:
#'
#' ```
#' if (getRversion() >= "3.6.0") {
#' S3method(package::generic, class)
#' }

所以,你只需要 不是 使用 @importFrom而不是 @export , 使用 @exportS3Method package::generic (见 https://github.com/r-lib/roxygen2/issues/796https://github.com/r-lib/roxygen2/commit/843432ddc05bc2dabc9b5b22c1ae7de507a00508)

插图

所以,为了说明,我们可以制作两个 非常简单的包裹, foobar .包裹 foo只是有一个通用的 foo()功能和默认方法:
library(devtools)
create_package("foo")

#' foo generic
#'
#' @param x An object
#' @param ... Arguments passed to or from other methods
#' @export
foo <- function(x, ...) {
UseMethod("foo", x)
}
#' foo default method
#'
#' @param x An object
#' @param ... Arguments passed to or from other methods
#' @export
foo.default <- function(x, ...) {
print("Called default method for foo.")
}

document()install() ing,我们创建 bar :
create_package("bar")

这会创建一个 bar foo() 的方法:
#' bar method for foo
#'
#' @param x A bar object
#' @param ... Arguments passed to or from other methods
#'
#' @exportS3Method foo::foo
foo.bar <- function(x, ...) {
print("Called bar method for foo.")
}

重要的是,我们 必须加载 foo运行前打包 document() , 或 @exportS3Method不会工作。那是,
library(foo)
document()

但是,如果我们这样做,我们会在 NAMESPACE 中得到以下内容为 bar :
# Generated by roxygen2: do not edit by hand

S3method(foo::foo,bar)

我们必须手动添加 fooDESCRIPTION 中“建议” .

那么如果我们卸载 foo ,我们仍然可以安装 bar :
> remove.packages("foo")
Removing package from ‘/home/duckmayr/R/x86_64-pc-linux-gnu-library/4.0’
(as ‘lib’ is unspecified)
> install("bar")
✓ checking for file ‘/home/jb/bar/DESCRIPTION’ ...
─ preparing ‘bar’:
✓ checking DESCRIPTION meta-information ...
─ checking for LF line-endings in source and make files and shell scripts
─ checking for empty or unneeded directories
─ building ‘bar_0.0.0.9000.tar.gz’

Running /opt/R/4.0.0/lib/R/bin/R CMD INSTALL \
/tmp/Rtmp5Xgwqf/bar_0.0.0.9000.tar.gz --install-tests
* installing to library ‘/home/jb/R/x86_64-pc-linux-gnu-library/4.0’
* installing *source* package ‘bar’ ...
** using staged installation
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded from temporary location
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (bar)

关于r - 在不引入依赖关系的情况下,在 R 包中定义 S3 方法的首选方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61482561/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com