簡體   English   中英

源腳本以在R中分隔環境,而不是全局環境

[英]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函數的解決方案。 使用envirtoplevel.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM