R仅在本地作用域中加载库



是否可能使library()仅影响本地范围?

例如,我的脚本有一个lapply循环,它在其他脚本中source((代码;这些脚本加载它们自己的库,但我希望在执行这些脚本中的代码后清理命名空间,这样脚本1调用的包A中的函数就不会屏蔽脚本2调用的包B中的函数。

我知道有像modulesimport包这样的完整解决方案,但我希望首先有一个更简单的基本R解决方案,只有在需要时才能扩大规模。

使用loadNamespace("pkg")将加载'pkg'软件包的命名空间。使用library("pkg")还将将'pkg'软件包附加到R的搜索路径。您可以看到哪些命名空间使用loadedNamespaces()加载,哪些包使用search()附加。这些属性对R来说是全局的。换句话说,使它们成为局部属性是不可能的。

如果您希望在函数/映射reduce调用中使用library(),而不使用library()在当前R会话中附加包,那么,正如其他人所建议的那样,您可以在外部R进程中评估您的调用。

(免责声明:我是作者(我建议使用futures(future(,通过future.callr外部评估它们未来的框架将负责将所需的对象导出到外部R进程这里有一个例子:

library(future)
plan(future.callr::callr, workers = 1)
y <- lapply((1:3)/4, FUN = function(x) value(future({
library(gtools)
logit(x)
})))

请注意如何创建未来并立即检索其值,即value(future(...))。为了澄清这一事实,您可以使用:

eval_via_future <- function(expr, substitute = TRUE, envir = parent.frame()) {
if (substitute) expr <- substitute(expr)
f <- future::future(expr, substitute = FALSE, envir = envir)
future::value(f)
}
library(future)
plan(future.callr::callr, workers = 1)
y <- lapply((1:3)/4, FUN = function(x) eval_via_future({
library(gtools)
logit(x)
})))

如果你想避免让用户指定plan(),你可以:

eval_via_callr <- function(expr, substitute = TRUE, envir = parent.frame()) {
oplan <- future::plan()
on.exit(future::plan(oplan))
future::plan(future.callr::callr, workers = 1)
if (substitute) expr <- substitute(expr)
f <- future::future(expr, substitute = FALSE, envir = envir)
future::value(f)
}

所以你可以做:

y <- lapply((1:3)/4, FUN = function(x) eval_via_callr({
library(gtools)
logit(x)
}))

不加载或附加gtools(它显然加载futurecallr所需的其他包(;

> loadedNamespaces()
[1] "codetools"    "grDevices"    "listenv"      "future"       "ps"          
[6] "memuse"       "clisymbols"   "prompt"       "digest"       "crayon"      
[11] "rappdirs"     "R6"           "future.callr" "datasets"     "utils"       
[16] "callr"        "graphics"     "base"         "tools"        "parallel"    
[21] "compiler"     "processx"     "stats"        "globals"      "methods"     
> search()
[1] ".GlobalEnv"        "package:stats"     "package:graphics" 
[4] "package:grDevices" "package:utils"     "package:datasets" 
[7] "CBC tools"         "toolbox:default"   "package:methods"  
[10] "Autoloads"         "package:base" 

更新2020-07-26

以下是如何通过未来在外部R进程中获取R脚本,同时从主R会话中提取全局:

future_source <- function(file, envir = parent.frame(), ...) {
expr <- parse(file = file, keep.source = FALSE)
expr <- bquote({..(expr)}, splice = TRUE)
future::future(expr, substitute = FALSE, envir = envir, ...)
}
source_via_callr <- function(file, envir = parent.frame()) {
oplan <- future::plan()
on.exit(future::plan(oplan))
future::plan(future.callr::callr, workers = 1)
f <- future_source(file, envir = envir)
future::value(f)
}
## Two R scripts
cat("log(a)n", file="a.R")
cat("library(gtools)nlogit(a)n", file="b.R")
## A global
a <- 0.42
## Source scripts in external process
y <- lapply(c("a.R", "b.R"), FUN = source_via_callr)

相关内容

  • 没有找到相关文章

最新更新