amit amit - 4 years ago 94
R Question

Binding outside variables in R

Suppose I have the following function:

g = function(x) x+h


Now, if I have in my environment an object named
h
, I would not have any problem:

h = 4
g(2)

## should be 6


Now, I have another function:

f = function() {
h = 3
g(2)
}


I would expect:

rm(h)
f()

## should be 5, isn't it?


Instead, I get an error

## Error in g(2) : object 'h' not found


I would expect
g
to be evaluated within the environment of
f
, so that the
h
in
f
will be bound to the h in g, as it was when I executed
g
within the
.GlobalEnv
. This does not happen (obviously). any explanation why? how to overcome this so that the function within the function(e.g.
g
) will be evaluated using the enclosing environment?

Answer Source

There's a difference between the enclosing environment of a function, and its (parent) evaluation frame.

The enclosing environment is set when the function is defined. If you define your function g at the R prompt:

g = function(x) x+h

then the enclosing environment of g will be the global environment. Now if you call g from another function:

f = function() {
    h = 3
    g(2)
}

the parent evaluation frame is f's environment. But this doesn't change g's enclosing environment, which is a fixed attribute that doesn't depend on where it's evaluated. This is why it won't pick up the value of h that's defined within f.

If you want g to use the value of h defined within f, then you should also define g within f:

f = function() {
    h = 3
    g = function(x) x+h
    g(2)
}

Now g's enclosing environment will be f's environment (but be aware, this g is not the same as the g you created earlier at the R prompt).

Alternatively, you can modify the enclosing environment of g as follows:

f = function() {
    h = 3
    environment(g) <- environment()
    g(2)
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download