I am trying to overwrite variable a in 'outer_func' with a value from 'inner_func'. I do not want it to produce a variable a outside of the function 'outer_func'.
inner_func <- function(){
a <<- 30
}
outer_func <- function(){
a <- 10
inner_func()
print(a)
}
outer_func()
The output is 10, but it should be 30.
You can use assign with the parent.frame() (parent.frame() s the environment of the outer function, parent.frame(2) would be global environment in this case):
inner_func <- function(){
assign("a", 30, envir = parent.frame())
}
outer_func <- function(){
a <- 10
inner_func()
print(a)
}
outer_func()
However be careful, because using side effects like makes the code much more complicated, and usually is inadvisable.
Here are 3 alternatives. (1) makes no changes to inner_func and (3) makes no changes to outer_func.
1) copy and reset environment of inner_func Make a copy of inner_func within outer_func and coerce the current environment to the copy. No changes are made to inner_func and only one line is added to outer_func and that both makes the copy and changes its environment.
outer_func <- function() {
a <- 10
environment(inner_func) <- environment()
inner_func()
print(a)
}
outer_func()
## [1] 30
2) nest inner_func in outer_func Another way to do this is to nest inner_func within outer_func.
outer_func <- function() {
inner_func <- function() {
a <<- 30
}
a <- 10
inner_func()
print(a)
}
outer_func()
## [1] 30
3) pass environment via arg Another way is to pass the environment where a is located to inner_func via an argument. By making the parent frame the default value of that argument we can avoid having to make any changes to outer_func.
inner_func <- function(envir = parent.frame()) {
envir$a <- 30
}
outer_func <- function() {
a <- 10
inner_func()
print(a)
}
outer_func()
## [1] 30
Any of these can be extended to set particular matrix elements if a is defined, say, as this in outer_func.
a <- matrix(1:4, 2)
In (1) and (2) modify inner_func to use, for example:
a[1,1] <<- 30
and in (3) use, for example, this in inner_func:
envir$a[1,1] <- 30
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