Reputation: 744
I have one function inside another like this:
func2 <- function(x=1) {ko+x+1}
func3= function(l=1){
ko=2
func2(2)+l
}
func3(1)
it shows error: Error in func2(2) : object 'ko' not found
. Basically I want to use object ko
in func2
which will not be define until func3
is called. Is there any fix for this?
Upvotes: 2
Views: 1227
Reputation: 1141
This is a good case for learning about closures and using a factory.
func3_factory <- function (y) {
ko <- y
func2 <- function (x = 1) { ko + x + 1 }
function (l = 1) { func2(2) + l }
}
ko <- 1
func3_ko_1 <- func3_factory(ko)
ko <- 7
func3_ko_7 <- func3_factory(ko)
# each function stores its own value for ko
func3_ko_1(1) # 5
func3_ko_7(1) # 11
# changing ko in the global scope doesn't affect the internal ko values in the closures
ko <- 100
func3_ko_1(1) # 5
func3_ko_7(1) # 11
When func3_factory
returns a function, that new function is coupled with the environment in which it was created, which in this case includes a variable named ko
which keeps whatever value was passed into the factory and a function named func2
which can also access that fixed value for ko
. This combindation of a function and the environemnt it was defined in is called a closure. Anything that happens inside the returned function can access these values, and they stay the same even if that ko
variable is changed outside the closure.
Upvotes: 0
Reputation: 206167
You don't really have one function "inside" the other currently (you are just calling a function within a different function). If you did move the one function inside the other function, then this would work
func3 <- function(l=1) {
func2 <- function(x=1) {ko+x+1}
ko <- 2
func2(2)+l
}
func3(1)
Functions retain information about the environment in which they were defined. This is called "lexical scoping" and it's how R operates.
But in general I agree with @Roland that it's better to write functions that have explicit arguments.
Upvotes: 3
Reputation: 132616
Yes, it can be fixed:
func2 <- function(x=1) {ko+x+1}
func3= function(l=1){
ko=2
assign("ko", ko, environment(func2))
res <- func2(2)+l
rm("ko", envir = environment(func2))
res
}
func3(1)
#[1] 6
As you see this is pretty complicated. That's often a sign that you are not following good practice. Good practice would be to pass ko
as a parameter:
func2 <- function(x=1, ko) {ko+x+1}
func3= function(l=1){
ko=2
func2(2, ko)+l
}
func3(1)
#[1] 6
Upvotes: 6