简体   繁体   English

源脚本以在R中分隔环境,而不是全局环境

[英]Source script to separate environment in R, not the global environment

Is there a way to source() a script in R such that it is attached as a parent to the global environment ( .GlobalEnv )? 是否有一种方法可以在R中对脚本进行source() ,使其作为父级附加到全局环境( .GlobalEnv )?

Currently, when I source a script, all variables and functions of that script appear in my global (interactive) environment. 当前,当我提供脚本时,该脚本的所有变量和函数都出现在我的全局(交互)环境中。 I'd like to include these variables and functions in the search path, but not in .GlobalEnv . 我想在搜索路径中包括这些变量和函数,但不在.GlobalEnv That is, I'd like the sourced script to behave like an attached package, which gets attached between the global and base environments (see figure from Advanced R Environments ) 也就是说,我希望源脚本的行为类似于附加包,该附加包在全局环境和基本环境之间附加(请参阅Advanced R Environments中的图

在此处输入图片说明

The simplest way to source a script as if it was a package (ie such that lexical scoping won't result in the use of variables defined in the global environment when calling functions defined in your R script) is to create an environment that that is whose parent is the .BaseNamespaceEnv , and then call source() using that environment. 像脚本一样打包脚本来获取脚本的最简单方法(即,在调用R脚本中定义的函数时, 词法作用域不会导致使用全局环境中定义的变量)。其父是.BaseNamespaceEnv ,然后使用该环境调用source()

For example if you have a script like this: 例如,如果您具有如下脚本:

# << my-script.R >>
my_fun <- function(x){x + y}

Then evaluating the following at the console, won't generate an error, as it would if my_fun were defined within it's own package: 然后在控制台上评估以下内容,不会产生错误,就像在自己的包中定义了my_fun一样:

source("my-script.R")
y = 2
my_fun(1)
#> 3

However, if you create an environment whose search() path does not include the Global Environment ( .GlobalEnv ) then you'll get a proper error when you call the function from your script: 但是,如果创建一个环境,其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

I would also like to a solution using sys.source function. 我也想使用sys.source函数的解决方案。 Using envir and toplevel.env arguments allows for convenient (IMHO) bypassing of the global environment. 使用envirtoplevel.env参数可以方便地绕过全局环境(IMHO)。 As per the linked documentation: 根据链接的文档:

sys.source [p]arses expressions in the given file, and then successively evaluates them in the specified environment. sys.source [p] sys.source给定文件中的表达式,然后在指定的环境中连续对其求值。

tstEnv <- new.env()
sys.source(file = "tst.R", envir = tstEnv, toplevel.env = tstEnv)

where tst.R contains: 其中tst.R包含:

a <- 1
b <- 1

Results: 结果:

ls(envir = .GlobalEnv)
# [1] "tstEnv"
ls(envir = tstEnv)
# [1] "a" "b"
tstEnv$a
# [1] 1

From the source documentation, the local argument can be an environment which determines where the sourced expressions are evaluated. source文档中, local参数可以是一个确定在何处评估源表达式的环境。

This suggests that you could create a new environment, run source passing this environment to local , then attach the environment to the search path. 这表明您可以创建一个新环境,运行将环境传递给local source ,然后attach环境attach到搜索路径。

Or you can use attach with what=NULL to create an empty environment, save the return value, and pass that to local in source : 或者,您可以使用attach和what=NULL来创建一个空环境,保存返回值,并将其传递给source local

tmp <- attach(what=NULL)
source('test.R', local=tmp)

or as a single line: 或作为一行:

source('test.R', local=attach(NULL))

The following environment insertion appears to achieve the desired functionality: 以下环境插入似乎可以实现所需的功能:

Check the current search path: 检查当前搜索路径:

search()
# [1] ".GlobalEnv"        "package:stats"     "package:graphics"
# [4] "package:grDevices" "package:utils"     "package:datasets"
# [7] "package:methods"   "Autoloads"         "package:base"

Add new environment for sourced packages and use local parameter when source() ing: 为source包添加新环境,并在source()时使用local参数:

myEnv <- new.env()    
source("some_other_script.R", local=myEnv)
attach(myEnv, name="sourced_scripts")

Check the search path: 检查搜索路径:

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"

Note that we attach() the new environment after sourcing, so that dplyr is attached after our script environment in the search path. 请注意,我们获取资源后将 attach()到新环境中,以便在搜索路径中的脚本环境之后附加dplyr

I'm not sure if my answer is any different from the answers given above, but I use the following code: 我不确定我的答案是否与上面给出的答案有所不同,但是我使用以下代码:

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.

相关问题 R - 创建一个单独的环境来源()一个R脚本,这样后者不会影响“调用者”环境 - R - Create a separate environment where to source() an R script, such that the latter does not affect the “caller” environment 用一个脚本设置 R 全局环境并用一秒钟访问它 - Set up R Global Environment with one script and access it with a second 在R中的全局环境中管理对象 - Manage objects in the global environment in R 在R中更改功能/全局环境 - Changing the functional/global environment in R 是否可以将变量从全局环境移动到单独的环境中? - Is it possible to move a variable from the global environment into a separate environment? 使用源R加载环境 - Load environment using source R 检测环境是否为全球环境 - Detect if environment is global environment 如何使全局环境中的用户定义函数的源代码在 R 中无法访问? (用于教育目的) - How to make source code of a user-defined function in global environment inaccessible in R? (for education purposes) 更改函数环境中的options()而不更改R中全局环境中的options()? - Changing options() in a function environment without changing options() in global environment in R? 是否可以在 R 中将 package 环境作为特定环境而不是全局环境的父级附加? - Is it possible to attach package environments as parents of a specific environment, not the global environment, in R?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM