Reputation: 781
I seem to be having trouble with function environments today. I have a bunch of objects, many of which are functions which call each other, saved to my drive as an .RData
file:
irrelevant_var <- 123
fun1 <- function(x) x+fun2(x)
fun2 <- function(x) x^2
save(irrelevant_var, fun1, fun2, file = "myEnv.RData")
rm(irrelevant_var, fun1, fun2)
I then load those objects into a new environment:
myEnv <- new.env()
load("myEnv.RData", envir = myEnv)
I then create a new meta function to work with the objects in myEnv
.
meta_fun <- function(x) fun1(x)
meta_fun(1)
Error in meta_fun(1) : could not find function "fun1"
Calling meta_fun
now won't work, because fun1
is in another environment, so I do this:
environment(meta_fun) <- myEnv
Now, I'm expecting a call to meta_fun
to work, and it finds fun1
but now cannot find fun2
.
meta_fun(1)
Error in fun1(x) : could not find function "fun2"
How can I get meta_fun
to work? Also, it isn't know beforehand how many functions are in myEnv
or how nested they are.
Upvotes: 1
Views: 502
Reputation: 206232
First, I would strongly encourage you to rethink your strategy. Trying to run code in specific environments (not attached to the search path) really isn't that fun.
Now, the problem is really with the environments of fun1
and fun2
. You define them in the global environment in this example so that's reflected in the environment()
properties of the function (functions capture the environment where they are defined). That means that despite the fact that the name fun1
lives in the myEnv
environment, that function has it's environment point to global, not myEnv
(it doesn't change because it's being reloaded, not redefined). Thus it cannot resolve the fun2
symbol. See:
environment(myEnv$fun1)
# <environment: R_GlobalEnv>
If you wanted to build those functions inside the environment, the a better way would be
myEnv <- new.env()
evalq({
fun1 <- function(x) x+fun2(x)
fun2 <- function(x) x^2
}, myEnv)
now check out the environment
environment(myEnv$fun1)
# <environment: 0x7ff507b31860>
myEnv
# <environment: 0x7ff507b31860>
Then you can either 1) define your meta_fun in the same environment
evalq(meta_fun <- function(x) fun1(x), myEnv)
meta_fun(4)
# [1] 20
or 2) change the environment of the meta_fun
as you did before
meta_fun <- function(x) fun1(x)
environment(meta_fun) <- myEnv
meta_fun(4)
# [1] 20
Also, i'm pretty sure attach()
doesn't make copies of objects unless you attempt to write to them. If you have a different reference for that, i'd be interested to see it.
Upvotes: 1