r - R 中的动态范围问题

标签 r eval dynamic-scope

我正在阅读 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。它搜索acondition 的值,并找到本地分配的符号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/

相关文章:

r - 在包开发中处理数据集依赖的正确方法?

r - 按两列分组并汇总多列

python - 在python中将字符串转换为元组

clojure - clojure 的动态变量和绑定(bind)的实际目的是什么?

haskell - 词法或动态范围 - Haskell 实现的评估器

scope - 词法范围与动态范围

r - ggplot : Log scale with linear labels

r - 如何从列表中删除元素?

Python用json传输代码

javascript - safari 中的 Eval 在正确的 es6 代码上抛出错误