评估:为什么enclos = parent.frame()有所作为? [英] eval: why does enclos = parent.frame() make a difference?
问题描述
在此问题中,以下内容引发错误:
In this question, the following throws an error:
subset2 = function(df, condition) {
condition_call = eval(substitute(condition),df )
df[condition_call,]
}
df = data.frame(a = 1:10, b = 2:11)
condition = 3
subset2(df, a < condition)
## Error in eval(substitute(condition), df) : object 'a' not found
最初问题中的乔什(Josh)和杰森(Jason)很好地解释了为什么会这样.我不明白的是为什么在eval中提供enclos
参数显然可以解决这个问题.
Josh and Jason from the original question did a great job explaining why this is. What I don't get is why supplying the enclos
argument to eval apparently fixes it.
subset3 = function(df, condition) {
condition_call = eval(substitute(condition), envir = df, enclos = parent.frame())
df[condition_call, ]
}
subset3(df, a < condition)
## a b
## 1 1 2
## 2 2 3
我知道跳过功能环境意味着R不再试图评估Promise,而是从全局环境中获取条件对象.
I understand that skipping the function environment means R is no longer trying to evaluate the promise, and instead grabs the condition object from the global environment.
但是我认为提供enclos = parent.frame()
应该没有什么不同.从?eval
的enclos参数开始:
But I think supplying enclos = parent.frame()
should not make a difference. From ?eval
on the enclos argument:
指定机箱,即R在其中查找在环境中找不到的对象.
Specifies the enclosure, i.e., where R looks for objects not found in envir.
但是,如果未提供,则默认为:
But if not provided, it defaults to:
enclos = if(is.list(envir) || is.pairlist(envir)) parent.frame() else baseenv())
在我看来,
无论如何应该解析为parent.frame()
,因为df
当然可以满足is.list()
的检查要求.
which, in my mind, should resolve to parent.frame()
anyway, because surely, df
satisfies the is.list()
check.
这意味着,只要某些对象data
在is.list()
上返回TRUE,eval(expr, envir = data)
和eval(expr, envir = data, enclos = parent.frame())
的行为就应该相同.但如上所述,事实并非如此.
This means that as long as some object data
returns TRUE on is.list()
, the behavior of eval(expr, envir = data)
and eval(expr, envir = data, enclos = parent.frame())
should be identical. But as evidenced by the above, it isn't.
我想念什么?
编辑:感谢SmokeyShakers指出了评估时间的默认参数和用户提供的参数之间的区别.我认为这实际上已经在这里表达了: https://stackoverflow.com/a/15505111/2416535
Thanks to SmokeyShakers who pointed out the difference between default and user-supplied arguments regarding the time of evaluation. I think this is actually already expressed here: https://stackoverflow.com/a/15505111/2416535
尽管可以使这个问题存活下来,这很有意义,因为它特别触及了eval()
(另一个问题则没有),并且在一个问题得到答案之前,认识到广义问题应该是什么并不容易.
It might make sense to keep this one alive though, as it touches eval()
specifically (the other does not), and it is not trivial to realize what the generalized question should be until one has the answer.
推荐答案
因此,父母不同.在不起作用的示例中,parent.frame
是从eval
内部查找到subset2
的内部环境的.在工作示例中,parent.frame
是从subset3
内部查找的,很可能是df所在的全局位置.
So, different parents. In the example that doesn't work parent.frame
is looking up from inside eval
into the internal environment of subset2
. In the working example, parent.frame
is looking up from inside subset3
, likely to your global where your df sits.
示例:
tester <- function() {
print(parent.frame())
}
tester() # Global
(function() {
tester()
})() # Anonymous function's internal env
这篇关于评估:为什么enclos = parent.frame()有所作为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!