Reputation: 2506
I have created two functions below that are both defined in the global environment. You'll notice that foo()
is called within bar()
and they share the one input which is x
. :
bar <- function() {
x <- 2
foo()
}
foo <- function(x) {
x * 1000
}
x
is not explicitly defined when foo()
is called within bar()
, which is causing an error with the following code:
bar()
My question is this: is there a way to define the environment where foo()
tries to find x
? From my research, foo()
is looking for x
in the global environment, but ideally it should be taking x
from the environment of bar()
, where x <- 2
.
I know that the following would fix the problem, but this isn't a reasonable option in the code I'm developing. The key is getting foo()
to reference the x
value from the environment of bar()
:
bar <- function() {
x <- 2
foo(x = x)
}
foo <- function(x) {
x * 1000
}
bar()
Upvotes: 0
Views: 93
Reputation: 206197
It seems like you maybe shoudl be using expressions here for functions like f
. Maybe
foo <- quote(x * 1000)
bar <- function() {
x <- 2
eval(foo)
}
bar()
#[1] 2000
Or if it does have to be a function
foo <- function() {
x * 1000
}
bar <- function() {
x <- 2
environment(foo)<-environment()
foo()
}
bar()
#[1] 2000
Note that this doesn't permanently change foo
, it just makes a local copy of foo
in bar
with a different enclosing environment.
The latter solution is much like my solution for the previous question: R specify function environment
Upvotes: 1
Reputation: 39325
This will give you something akin to what you want. The trick is to use a closure to define the function(/environment) you want, and then use the double left arrow assign to assign the value of x within bar
. Double left arrow assign gives you the ability to write to a variable in the parent environment.
make_foo_bar_pair = function() {
# Define the shared state...
x <- 0
# Make your bar function
bar <- function() {
x <<- 2 # Use the double left arrow assign to modify the shared state
foo()
}
# Make your foo function
foo <- function() {
x * 1000 # Which references the shared state
}
# Return your linked functions...
list(foo, bar)
}
# Make a pair of functions with shared state...
pair = make_foo_bar_pair()
foo = pair[[1]]
bar = pair[[2]]
# Call them
foo() # 0 (foo uses the initial value of x that it closed over)
bar() # 2000
foo() # 2000
Each foo
/bar
pair that you create will reference a different x
, so calling make_foo_bar_pair
repeatedly will give you fresh foo
/bar
functions sharing a distinct x
.
If you really need to use the global environment you could do this...
# Make your bar function
bar <- function() {
x <<- 2 # Use the double left arrow assign to modify the shared state
foo()
}
# Make your foo function
foo <- function() {
x * 1000 # Which references the shared state
}
...but doing things in the global environment like that feels like a code smell.
Upvotes: 1