如何解决将软件包附加到R中的“临时”搜索路径
在函数内部,我正在采购脚本:
quarkus.datasource.jdbc.driver
不幸的是,我所采购的脚本不受我的完全控制。他们呼叫f <- function(){
source("~/Desktop/sourceme.R") # source someone elses script
# do some stuff to the variables read in
}
f()
search() # library sourceme.R attaches is all the way in the back!
,并污染了搜索路径。
如果library(somePackage)
的作者期望他/她所附加的软件包位于全球环境的最高层/顶部,那么这将是一个主要问题。如果我本人已经附上了一些掩盖了他/她期望可用的某些功能名称的软件包,那是不好的。
有没有办法获取脚本,但是以某种方式使我自己的临时搜索路径在函数完成运行后“重置”?
解决方法
我会考虑使用callr
包在单独的R进程中采购脚本,然后返回由源文件创建的环境。
通过使用单独的R进程,可以防止您的搜索路径被污染。我猜想在您想要的全局环境中可能会有一些副作用(例如,定义变量的新函数)。 local
函数的source
自变量允许您指定应在何处执行已解析的脚本。如果从其他R进程返回此环境,则可以访问所需的任何结果。
不确定您的样子,但说我有这个文件会修改搜索路径:
# messWithSearchPath.R
library(dplyr)
a <- data.frame(groupID = rep(1:3,10),value = rnorm(30))
b <- a %>%
group_by(groupID) %>%
summarize(agg = sum(value))
在我的顶级脚本中,我将编写一个包装器函数以在新环境中获取它,并让callr
执行该函数:
RogueScript <- function(){
rogueEnv <- new.env()
source("messWIthSearchPath.R",local = rogueEnv)
rogueEnv
}
before <- search()
scriptResults <- callr::r(RogueScript)
scriptResults$b
#> groupID agg
#> 1 1 -2.871642
#> 2 2 3.368499
#> 3 3 1.159509
identical(before,search())
#> [1] TRUE
如果脚本还有其他副作用(例如设置选项或建立外部连接),则此方法可能无效。可能有变通办法,具体取决于它们要执行的操作,但是如果您只想创建变量/函数,则应该可以使用。它还可以防止脚本相互冲突,而不仅仅是顶级脚本。
,一种方法是“快照”您当前的搜索路径,并稍后尝试返回它:
search.snapshot <- local({
.snap <- character(0)
function(restore = FALSE) {
if (restore) {
if (is.null(.snap)) {
return(character(0))
} else {
extras <- setdiff(search(),.snap)
# may not work if DLLs are loaded
for (pkg in extras) {
suppressWarnings(detach(pkg,character.only = TRUE,unload = TRUE))
}
return(extras)
}
} else .snap <<- search()
}
})
实际情况:
search.snapshot() # store current state
get(".snap",envir = environment(search.snapshot)) # view snapshot
# [1] ".GlobalEnv" "ESSR" "package:stats"
# [4] "package:graphics" "package:grDevices" "package:utils"
# [7] "package:datasets" "package:r2" "package:methods"
# [10] "Autoloads" "package:base"
library(ggplot2)
library(zoo)
# Attaching package: 'zoo'
# The following objects are masked from 'package:base':
# as.Date,as.Date.numeric
library(dplyr)
# Attaching package: 'dplyr'
# The following objects are masked from 'package:stats':
# filter,lag
# The following objects are masked from 'package:base':
# intersect,setdiff,setequal,union
search()
# [1] ".GlobalEnv" "package:dplyr" "package:zoo"
# [4] "package:ggplot2" "ESSR" "package:stats"
# [7] "package:graphics" "package:grDevices" "package:utils"
# [10] "package:datasets" "package:r2" "package:methods"
# [13] "Autoloads" "package:base"
search.snapshot(TRUE) # returns detached packages
# [1] "package:dplyr" "package:zoo" "package:ggplot2"
search()
# [1] ".GlobalEnv" "ESSR" "package:stats"
# [4] "package:graphics" "package:grDevices" "package:utils"
# [7] "package:datasets" "package:r2" "package:methods"
# [10] "Autoloads" "package:base"
我有一点自信(未经验证),这可能并不总是适用于所有软件包,可能是由于依赖关系和/或加载的DLL。您可以尝试将force=TRUE
添加到detach
调用中,不确定这样做是否会更好,或者还有其他不良影响。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。