Is there a way to source()
a script in R such that it is attached as a parent to the global environment (.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
. 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)
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:
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.
The simplest way to source a script as if it was a package (i.e. 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.
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:
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:
# 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With