Scoping and functions in R 2.11.1 : What's going wrong?
Asked Answered
Y

4

14

This question comes from a range of other questions that all deal with essentially the same problem. For some strange reason, using a function within another function sometimes fails in the sense that variables defined within the local environment of the first function are not found back in the second function.

The classical pattern in pseudo-code :

ff <- function(x){
    y <- some_value
    some_function(y)
}
ff(x)

Error in eval(expr, envir, enclos) : object 'y' not found

First I thought it had something to do with S4 methods and the scoping in there, but it also happens with other functions. I've had some interaction with the R development team, but all they did was direct me to the bug report site (which is not the most inviting one, I have to say). I never got any feedback.

As the problem keeps arising, I wonder if there is a logic explanation for it. Is it a common mistake made in all these cases, and if so, which one? Or is it really a bug?

Some of those questions :

PS : I know the R-devel list, in case you wondered...

Yevetteyew answered 1/10, 2010 at 15:43 Comment(2)
I like your workaround on this one #3742915Cordage
I also contacted R-devel, and there I was told about the same as @Richie, @Jonathan, and @hadley told me. Thx to all for the valuable answers.Yevetteyew
C
3

As Dirk mentioned in his answer, there isn't actually a problem with the code that you posted. In the links you posted in the question, there seems to be a common theme: some_function contains code that messes about with environments in some way. This messing is either explicit, using new.env and with or implicitly, using a data argument, that probably has a line like

y <- eval(substitute(y), data)

The moral of the story is twofold. Firstly, try to avoid explicitly manipulating environments, unless you are really sure that you know what you are doing. And secondly, if a function has a data argument then put all the variables that you need the function to use inside that data frame.

Countrywoman answered 4/10, 2010 at 12:48 Comment(1)
As I answered Dirk, I know there isn't a problem with that code. It was just an illustration. Thx for the answer, that sums it up pretty nicely I guess. And thx for the tip, that will definitely avoid me a lot of frustration. Accepted.Yevetteyew
F
5

R has both lexical and dynamic scope. Lexical scope works automatically, but dynamic scope must be implemented manually, and requires careful book-keeping. Only functions used interactively for data analysis need dynamic scope, so most authors (like me!) don't learn how to do it correctly.

See also: the standard non-standard evaluation rules.

Facility answered 1/10, 2010 at 19:50 Comment(0)
L
4

There are undoubtedly bugs in R, but a lot of the issues that people have been having are quite often errors in the implementation of some_function, not R itself. R has scoping rules ( see http://cran.r-project.org/doc/manuals/R-intro.html#Scope) which when combined with lazy evaluation of function arguments and the ability to eval arguments in other scopes are extremely powerful but which also often lead to subtle errors.

Lowpitched answered 1/10, 2010 at 17:29 Comment(0)
C
3

As Dirk mentioned in his answer, there isn't actually a problem with the code that you posted. In the links you posted in the question, there seems to be a common theme: some_function contains code that messes about with environments in some way. This messing is either explicit, using new.env and with or implicitly, using a data argument, that probably has a line like

y <- eval(substitute(y), data)

The moral of the story is twofold. Firstly, try to avoid explicitly manipulating environments, unless you are really sure that you know what you are doing. And secondly, if a function has a data argument then put all the variables that you need the function to use inside that data frame.

Countrywoman answered 4/10, 2010 at 12:48 Comment(1)
As I answered Dirk, I know there isn't a problem with that code. It was just an illustration. Thx for the answer, that sums it up pretty nicely I guess. And thx for the tip, that will definitely avoid me a lot of frustration. Accepted.Yevetteyew
D
0

Well there is no problem in what you posted:

/tmp$ cat joris.r 
#!/usr/bin/r -t

some_function <- function(y) y^2

ff <- function(x){
    y <- 4
    some_function(y)  # so we expect 16
}
print(ff(3))          # 3 is ignored
$ ./joris.r 
[1] 16
/tmp$

Could you restate and postan actual bug or misfeature?

Derbyshire answered 1/10, 2010 at 17:32 Comment(3)
He provided links to 5 examples.Cordage
Cool, what's next. Reference to just go and look it up on the intertubes yourself ? Sorry, concrete help for concrete and tangible questions. Joris is very smart cookie, and I'd be glad to try to help with explicit questions.Derbyshire
My question is about the link between the five bugs. I couldn't really copy-paste the whole discussion held there, could I?Yevetteyew

© 2022 - 2024 — McMap. All rights reserved.