Pan
Pan

Reputation: 938

Nested function in R

Why the following nested function f2 doesn't work as expected?

c = 2
f1 = function(a,b){
    (a+b)*c
}
f1(1,2) # 6

f2 = function(a,b,c){
    f1(a,b)
}
f2(1,2,c=3) # still 6, expect 9

Update

I found the following modification works:

f2 = function(a,b,c){
    c <<- c
    f1(a,b)
}
f2(1,2,c=3) # returns 9 as expected

But I am confused about the how a function call searches values along the path of environments. If my problem is just due to R's lazy evaluation, I just need c <- c. Then the new c will be in the environment where f2 is called. Since f1 is nested in f2, its environment is nested in that of f2. So when I need c in f1, it should be able to find c in the parent environment. However, it turns out that it can only find the global c, not the c in f2's environment.

Upvotes: 1

Views: 3252

Answers (1)

chaslewis
chaslewis

Reputation: 306

R has lexical scope; a variable that is not assigned in a function is resolved against its static environment. In your case, f1 sees the value of c in your global environment, which is 2. Within f2, c == 3 because it is passed as an argument which masks the global c, but when f1 is called, it still sees c==2 from its enclosing environment. You expected dynamic scoping, where c would take the value of its runtime environment (i.e., within f2). You can set c <- 3 outside the functions, before f2, or you can do this to copy the local value passed as 'c' in f2 to the global environment:

 f2 = function(a,b,c){
    c <<- c     # local argument c copied to global c
    f1(a,b)
 }

more discussion of lexical scope in R: https://darrenjw.wordpress.com/2011/11/23/lexical-scope-and-function-closures-in-r/

Upvotes: 5

Related Questions