首页 > 解决方案 > R包 - 从导入的包中转移环境

问题描述

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

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

$ cat NAMESPACE
import(RCircos)
...

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

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

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

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

那么可以做些什么呢?

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

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

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

但是,CRAN 检查会用一个 NOTE 突出显示这一行,从而阻止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 检查通过警告突出显示此选项,再次阻止myPackage在 CRAN 上的接受。

* 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可访问诸如RCircos.Set.Core.ComponentsmyPackage 之类的函数!有人可以命名并解释这种方式吗?

标签: rpackageenvironmentcrancircos

解决方案


显然,正常的重新导出不适用于环境,因为它适用于功能。但这确实有效:

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 函数通常不应该有副作用,例如编辑看不见的环境。设置默认值等通常使用options(). 整个包可能不是您想要模仿的东西,但至少现在您可以将它用作依赖项。


推荐阅读