【问题标题】:R package - Transferring environment from imported packageR包 - 从导入的包中转移环境
【发布时间】:2019-07-03 18:21:12
【问题描述】:

假设一个 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 包识别;例如,参见 this 包的第 247-249 行)。

不幸的是,当我通过描述文件和命名空间文件。

那么有什么办法呢?

似乎有两种选择可以让RCircos.Initialize.Plot.Parameters 等函数可以访问环境RCircos.Env。但是,这两个选项都会导致 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 检查会用 NOTE 突出显示这一行,从而阻止在 CRAN 上接受 myPackage

* 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 环境可供 myPackage 中的 RCircos.Set.Core.Components 等函数访问!有人可以这样命名和解释吗?

【问题讨论】:

  • 你试过导出环境吗?即@importFrom RCircos RCircos.Env 然后@export 使用 {roxygen2}
  • 作为用户使用RCircos时,通常如何在全局环境中获得RCircos.EnvXGR 似乎只是调用像 RCircos.Set.Core.Components() 这样的函数,就我所见,从不为全局环境分配任何东西。
  • @Axeman @seasmith 所以,我做了一些挖掘工作。当您通过 NAMESPACE 导入包时,似乎不会传输环境及其变量。这就是为什么在 myPackage 中无法识别环境 RCircos.Env 的原因,即使我在DESCRIPTION 中将RCircos 作为myPackage 的导入文件。对吗?
  • 你应该可以访问RCircos::RCircos.Env,并且可以重新导出它,正如seasmith所说。 That's e.g. what dplyr does with the %&gt;% operator from magrittr。但这并不能解决您不允许写入全局环境的 CRAN 问题
  • @Axeman 那么,RCircos 最初是如何被 CRAN 接受的呢? (这似乎是鸡/蛋的问题。)

标签: r package environment cran circos


【解决方案1】:

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

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() 完成。整个包可能不是您想要模仿的东西,但至少现在您可以将它用作依赖项。

【讨论】:

  • 哇,我向你脱帽致敬!你的回答确实解决了这个问题。话虽如此,我仍然必须在NAMESPACE 中包含export(RCircos.Env)(正如您在帖子的早期版本中所建议的那样)才能使我的包正常工作。
猜你喜欢
  • 2012-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多