R 包 - 从导入包传输环境

R package - Transferring environment from imported package

假设一个 R 包 (myPackage) 通过 DESCRIPTION 文件和 NAMESPACE 文件导入 R 包 RCircos

$ cat DESCRIPTION
Package: myPackage
Imports: RCircos (>= 1.2.0)
...

$ cat NAMESPACE
import(RCircos)
...

RCircos 的好处之一是它定义了自定义环境(称为 RCircos.Env)和 reads/writes 从它的各种功能到这个环境的变量。例如,函数 RCircos.Initialize.Plot.Parameters 读取和写入此环境。

...
RCircosEnvironment <- NULL;
RCircosEnvironment <- get("RCircos.Env", envir = globalenv());
RCircosEnvironment[["RCircos.PlotPar"]] <- plot.param;

(这种特殊行为也已被其他 R 包识别;例如,参见 this 包的第 247-249 行)。

不幸的是,当我简单地导入时,RCircos.Env 中的环境似乎无法立即识别 myPackage RCircos 通过 DESCRIPTION 文件和 NAMESPACE 文件。

那么可以做什么呢?

似乎有两种选择可以使环境 RCircos.Env 可供 RCircos.Initialize.Plot.Parameters 等函数访问。然而,这两个选项都会导致 CRAN 检查(R CMD check myPackage --as-cran)在提交给 CRAN 之前对 myPackage 的强制评估期间发出警告或注释,从而阻止其接受CRAN.

选项 1:我在要求对象的函数之前直接添加了以下行:

# my code here #
assign("RCircos.Env", RCircos::RCircos.Env, .GlobalEnv)
RCircos.Set.Core.Components(...)
# my code here #

然而,CRAN 检查用注释突出显示了这一行,从而阻止了 myPackage 在 CRAN 上的接受。

* checking R code for possible problems ... NOTE
Found the following assignments to the global environment:
File ‘PACViR/R/visualizeWithRCircos.R’:
  assign("RCircos.Env", RCircos::RCircos.Env, .GlobalEnv)

选项 2:我在需要对象的函数之前加载整个 RCircos 库:

# my code here #
library(RCircos)
RCircos.Set.Core.Components(...)
# my code here #

然而,CRAN 检查通过警告突出显示此选项,再次阻止在 CRAN 上接受 myPackage

* checking dependencies in R code ... WARNING
'library' or 'require' call not declared from: ‘RCircos’
'library' or 'require' call to ‘RCircos’ in package code.
  Please use :: or requireNamespace() instead.
  See section 'Suggested packages' in the 'Writing R Extensions' manual.

当然,必须有一种简单且与 CRAN 兼容的方法来使环境 RCircos.Env 可供 [=44 中的 RCircos.Set.Core.Components 等功能访问=]我的包裹!有人可以这样命名和解释吗?

显然,正常的 re-export 不适用于环境,因为它适用于函数。但这确实有效:

RCircos.Env <- RCircos::RCircos.Env

#' test
#'
#' @param ... data
#'
#' @export
test_fun <- function(...) {
  RCircos::RCircos.Set.Core.Components(...)
}

DESCRIPTION:

Package: test
Type: Package
Title: test
Description: This is a description.
Version: 0.1.0
Authors@R: person("Wouter", "van der Bijl",
                  email = "redacted@redacted.com",
                  role = c("aut", "cre"))
Maintainer: Wouter van der Bijl <redacted@redacted.com>
License: GPL-3
Encoding: UTF-8
LazyData: true
Imports: RCircos
RoxygenNote: 6.1.1

还有这个NAMESPACE

# Generated by roxygen2: do not edit by hand

export(test_fun)

测试:

library(test)
data(UCSC.HG19.Human.CytoBandIdeogram, package = 'RCircos')
test_fun(UCSC.HG19.Human.CytoBandIdeogram)

基本上,当 RCircos 运行 get("RCircos.Env", envir = globalenv()) 时,它将遍历搜索路径,直到从您的包中找到 RCircos.Env

当 运行 R CMD Check 我得到 0 个错误,0 个警告,0 个注释。


请注意,RCircos 使用的这种策略,以及使用 get(.., envir = globalenv()) 查找的环境确实是非正统的,通常不是一个好主意。 R函数一般不应该有side-effects,比如编辑看不见的环境。设置默认值等通常使用 options() 完成。整个包可能不是您想要模拟的东西,但至少现在您可以将它用作依赖项。