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
eval(expr, envir, enclos)中的错误:没有找到对象'y'
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.
首先,我认为它与S4方法和范围有关,但它也与其他函数有关。我曾与R开发团队进行过一些交流,但他们所做的只是将我引向bug报告站点(我不得不说,这不是最吸引人的站点)。我从来没有得到过任何反馈。
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?
随着问题的不断出现,我怀疑是否有合理的解释。这是所有这些案件中常见的错误吗?如果是,是哪一个?或者它真的是一个bug?
Some of those questions :
其中的一些问题:
- Using functions and environments
- 使用功能和环境
- R (statistical) scoping error using transformBy(), part of the doBy package.
- R(统计)使用transformBy()来确定范围错误,transformBy()是doBy包的一部分。
- How to use acast (reshape2) within a function in R?
- 如何在函数R中使用acast (reshape2) ?
- Why can't I pass a dataset to a function?
- 为什么我不能把数据集传递给函数?
- Values not being copied to the next local environment
- 值不被复制到下一个本地环境
PS : I know the R-devel list, in case you wondered...
我知道R-devel的名单,如果你想知道……
4 个解决方案
#1
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
正如Dirk在他的回答中提到的,你发布的代码实际上没有问题。在您发布的问题的链接中,似乎有一个共同的主题:some_function包含一些代码,这些代码在某种程度上与环境有关。这个混乱要么是显式的,使用new。使用数据参数env或隐式地,可能有一条类似的行。
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.
这个故事的寓意是双重的。首先,尽量避免显式地操纵环境,除非你真的确定自己知道自己在做什么。其次,如果一个函数有一个数据参数,那么把你需要的所有变量都放到数据框中。
#2
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.
R具有词汇和动态范围。词法作用域是自动工作的,但是动态作用域必须手动实现,并且需要仔细的簿记。只有交互地用于数据分析的函数才需要动态范围,所以大多数作者(比如我!)都不知道如何正确地进行数据分析。
See also: the standard non-standard evaluation rules.
参见标准非标准评价规则。
#3
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.
毫无疑问,在R中有错误,但是人们遇到的很多问题都是在some_function的实现中出现的错误,而不是R本身。R有范围规则(参见http://cran.r-project.org/doc/manuals/R-intro.html#作用域),它结合了对函数参数的延迟评估,以及在其他范围内eval参数的能力非常强大,但也常常导致一些细微的错误。
#4
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?
你能重申和postan真正的bug或错误特征吗?
#1
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
正如Dirk在他的回答中提到的,你发布的代码实际上没有问题。在您发布的问题的链接中,似乎有一个共同的主题:some_function包含一些代码,这些代码在某种程度上与环境有关。这个混乱要么是显式的,使用new。使用数据参数env或隐式地,可能有一条类似的行。
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.
这个故事的寓意是双重的。首先,尽量避免显式地操纵环境,除非你真的确定自己知道自己在做什么。其次,如果一个函数有一个数据参数,那么把你需要的所有变量都放到数据框中。
#2
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.
R具有词汇和动态范围。词法作用域是自动工作的,但是动态作用域必须手动实现,并且需要仔细的簿记。只有交互地用于数据分析的函数才需要动态范围,所以大多数作者(比如我!)都不知道如何正确地进行数据分析。
See also: the standard non-standard evaluation rules.
参见标准非标准评价规则。
#3
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.
毫无疑问,在R中有错误,但是人们遇到的很多问题都是在some_function的实现中出现的错误,而不是R本身。R有范围规则(参见http://cran.r-project.org/doc/manuals/R-intro.html#作用域),它结合了对函数参数的延迟评估,以及在其他范围内eval参数的能力非常强大,但也常常导致一些细微的错误。
#4
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?
你能重申和postan真正的bug或错误特征吗?