我正在阅读 Hadley 的 AdvancedR,并在此 URL 上测试以下代码
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
我读了如下解释,但不太明白:
If eval() can’t find the variable inside the data frame (its second argument), it looks in the environment of subset2(). That’s obviously not what we want, so we need some way to tell eval() where to look if it can’t find the variables in the data frame.
在我看来,当“eval(substitute(condition),df )”时,他们找不到的变量是condition,那么为什么找不到对象“a”呢?
另一方面,为什么下面的代码不会出错?
subset2 = function(df, condition){
condition_call = eval(substitute(condition),df )
df[condition_call,]
}
df = data.frame(a = 1:10, b = 2:11)
y = 3
subset2(df, a < y)
最佳答案
这个更加精简的示例可能会让您更容易了解 Hadley 示例中发生的情况。首先要注意的是,符号 condition
在这里以四个不同的角色出现,我已经用编号注释标记了每个角色。
## Role of symbol `condition`
f <- function(condition) { #1 -- formal argument
a <- 100
condition + a #2 -- symbol bound to formal argument
}
condition <- 3 #3 -- symbol in global environment
f(condition = condition + a) #4 -- supplied argument (on RHS)
## Error in f(condition = condition + a) (from #1) : object 'a' not found
要理解的另一件重要的事情是,在提供的参数中的符号(这里是 #4
处的 condition = condition + a
的右侧部分)在调用函数的评估框架。来自 Section 4.3.3 Argument Evaluation R 语言定义:
One of the most important things to know about the evaluation of arguments to a function is that supplied arguments and default arguments are treated differently. The supplied arguments to a function are evaluated in the evaluation frame of the calling function. The default arguments to a function are evaluated in the evaluation frame of the function.
在上面的示例中,调用 f()
的评估框架是全局环境 .GlobalEnv
。
按照此步骤,调用 (condition = condition + a)
时会发生以下情况。在函数求值期间,R 在函数体中(在 #2
处)遇到表达式 condition + a
。它搜索a
和condition
的值,并找到本地分配的符号a
。它发现符号 condition
绑定(bind)到名为 condition
的形式参数(位于 #1
)。在函数调用期间提供的形式参数的值是condition + a
(位于#4
)。
如 R 语言定义中所述,表达式 condition + a
中的符号值在调用函数的环境(此处为全局环境)中搜索。由于全局环境包含名为 condition
的变量(在 #3
处分配),但没有名为 a
的变量,因此无法计算表达式 condition + a
(位于 #4
),并失败并出现您看到的错误。
关于r - R 中的动态范围问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51699452/