Reputation: 3057
I am embarrassed that I'm asking this question, and I wonder if it has something fundamental to do with scoping that I'm not understanding.
i have two functions, beta
and alpha
beta <- function(b) {
foo <- b + x
print(foo)
}
and
alpha <- function(a) {
x <- a + 5
print(x)
beta(2)
}
When I run alpha(1)
I'm expecting the output of beta
to be 8. However, I get an error message about object 'x' not being found.
Question: shouldn't beta
know that x is 6? I think I am missing something obvious.
Upvotes: 1
Views: 56
Reputation: 7858
The problem is that both alpha
and beta
are declared inside the Global Environment.
Every function looks for unknown objects into the parent environment.
beta
's parent environment is the global environment, so when x
is called beta
will look for x
in the Global Environment: it can't "see" what was created inside alpha
's environment.
It would work as you expect:
beta
inside alpha
environment:alpha <- function(a) {
beta <- function(b) {
foo <- b + x
print(foo)
}
x <- a + 5
print(x)
beta(2)
}
alpha(1)
#> [1] 6
#> [1] 8
beta
in which environment it should look for x
:beta <- function(b, env = parent.frame()) {
x <- get("x", envir = env)
foo <- b + x
print(foo)
}
alpha <- function(a) {
x <- a + 5
print(x)
beta(2) # by default beta takes alpha's environment as parent frame!
}
alpha(1)
#> [1] 6
#> [1] 8
There are also other options, like assigning x
to the alpha's parent environment, but I wouldn't do that.
beta <- function(b) {
foo <- b + x
print(foo)
}
alpha <- function(a) {
x <<- a + 5
print(x)
beta(2)
}
alpha(1)
#> [1] 6
#> [1] 8
I would suggest you to have a look at this.
Upvotes: 2
Reputation: 73692
What about specifying x
in beta()
?
beta <- function(b, x) {
foo <- b + x
print(foo)
}
alpha <- function(a) {
x <- a + 5
print(x)
beta(2, x)
}
alpha(1)
# [1] 6
# [1] 8
Upvotes: 1
Reputation: 10375
R
uses lexical scoping. That means that values are first looked up in the function itself and then in the environment where the function was defined.
When you define both alpha
and beta
in the global environment, beta
looks up x
in the global environment.
beta <- function(b) {
foo <- b + x
print(foo)
}
alpha <- function(a) {
x <- a + 5
print(x)
beta(2)
}
alpha(1)
#> [1] 6
#> Error in beta(2): object 'x' not found
Created on 2021-11-19 by the reprex package (v1.0.0)
In contrast, if you define beta
within alpha
, x
is found (because x
is also defined in the environment where beta
is defined):
alpha <- function(a) {
x <- a + 5
print(x)
beta <- function(b) {
foo <- b + x
print(foo)
}
beta(2)
}
alpha(1)
#> [1] 6
#> [1] 8
Created on 2021-11-19 by the reprex package (v1.0.0)
Upvotes: 2