![](/img/trans.png)
[英]R - Create a separate environment where to source() an R script, such that the latter does not affect the “caller” environment
[英]Source script to separate environment in R, not the global environment
是否有一種方法可以在R中對腳本進行source()
,使其作為父級附加到全局環境( .GlobalEnv
)?
當前,當我提供腳本時,該腳本的所有變量和函數都出現在我的全局(交互)環境中。 我想在搜索路徑中包括這些變量和函數,但不在.GlobalEnv
。 也就是說,我希望源腳本的行為類似於附加包,該附加包在全局環境和基本環境之間附加(請參閱Advanced R Environments中的圖 )
像腳本一樣打包腳本來獲取腳本的最簡單方法(即,在調用R腳本中定義的函數時, 詞法作用域不會導致使用全局環境中定義的變量)。其父是.BaseNamespaceEnv
,然后使用該環境調用source()
。
例如,如果您具有如下腳本:
# << my-script.R >>
my_fun <- function(x){x + y}
然后在控制台上評估以下內容,不會產生錯誤,就像在自己的包中定義了my_fun
一樣:
source("my-script.R")
y = 2
my_fun(1)
#> 3
但是,如果創建一個環境,其search()
路徑不包括全局環境( .GlobalEnv
),則從腳本中調用該函數時,將得到正確的錯誤:
# Create the environment:
ENV = new.env(parent = .BaseNamespaceEnv)
# Attache it to the search path so that objects in your environment can be
# found from the global environment (i.e. from the console):
attach(ENV)
# do things:
source("my-script.R",ENV)
y = 2
my_fun(1)
#> Error in .ENV$my_fun(3) : object 'y' not found
我也想使用sys.source
函數的解決方案。 使用envir
和toplevel.env
參數可以方便地繞過全局環境(IMHO)。 根據鏈接的文檔:
sys.source
[p]sys.source
給定文件中的表達式,然后在指定的環境中連續對其求值。
tstEnv <- new.env()
sys.source(file = "tst.R", envir = tstEnv, toplevel.env = tstEnv)
其中tst.R
包含:
a <- 1
b <- 1
ls(envir = .GlobalEnv)
# [1] "tstEnv"
ls(envir = tstEnv)
# [1] "a" "b"
tstEnv$a
# [1] 1
從source
文檔中, local
參數可以是一個確定在何處評估源表達式的環境。
這表明您可以創建一個新環境,運行將環境傳遞給local
source
,然后attach
環境attach
到搜索路徑。
或者,您可以使用attach和what=NULL
來創建一個空環境,保存返回值,並將其傳遞給source
local
:
tmp <- attach(what=NULL)
source('test.R', local=tmp)
或作為一行:
source('test.R', local=attach(NULL))
以下環境插入似乎可以實現所需的功能:
檢查當前搜索路徑:
search()
# [1] ".GlobalEnv" "package:stats" "package:graphics"
# [4] "package:grDevices" "package:utils" "package:datasets"
# [7] "package:methods" "Autoloads" "package:base"
為source包添加新環境,並在source()
時使用local
參數:
myEnv <- new.env()
source("some_other_script.R", local=myEnv)
attach(myEnv, name="sourced_scripts")
檢查搜索路徑:
search()
# [1] ".GlobalEnv" "sourced_scripts" "package:dplyr"
# [4] "package:stats" "package:graphics" "package:grDevices"
# [7] "package:utils" "package:datasets" "package:methods"
# [10] "Autoloads" "package:base"
請注意,我們在獲取資源后將 attach()
到新環境中,以便在搜索路徑中的腳本環境之后附加dplyr
。
我不確定我的答案是否與上面給出的答案有所不同,但是我使用以下代碼:
if (!exists('.env')) .env <- new.env() # creates an environment in which to store functions
if ('.env' %in% search()) detach(.env) # detaches .env if it already exists; does not "erase" functions previously stored in .env
func <- "filenameWhereSourceCodeIsStored"
source(paste0("C:/Users/JT/R/Functions/", func, ".R"), .env)
attach(.env)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.