首页 > 解决方案 > Dynamic scoping questions in R

问题描述

I'm reading the AdvancedR by Hadley and am testing the following code on this 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)

Then I got the following error message:

Error in eval(substitute(condition), df) : object 'a' not found

I read the explanation as follows but don't quite understand:

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.

In my opinion, while "eval(substitute(condition),df )", the variable they cannot find is condition, then why object "a" cannot be found?

On the other hand, why the following code won't make any error?

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)

标签: revaldynamic-scope

解决方案


这个更精简的例子可能会让你更容易看到 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

要理解的另一件重要的事情是在调用函数的评估框架中搜索提供的参数中的符号(这里是condition = condition + aat的右侧部分)。#4第 4.3.3 节R 语言定义的参数评估:

关于函数参数的评估,最重要的事情之一是提供的参数和默认参数的处理方式不同。提供给函数的参数在调用函数的评估框架中进行评估。函数的默认参数在函数的评估框架中评估。

在上面的例子中,调用的评估框架f()是全局环境,.GlobalEnv.

一步一步来,当你调用(condition = condition + a). 在函数求值期间,R 遇到condition + a函数体 (at #2) 中的表达式。它搜索 和 的值,acondition找到一个本地分配的符号a。它发现符号condition绑定到名为condition(at #1) 的形式参数。在函数调用期间提供的形式参数的值是condition + a(at #4)。

如 R 语言定义中所述,表达式中符号的值是condition + a在调用函数的环境中搜索的,这里是全局环境。由于全局环境包含一个名为condition(分配在#3)的变量,但没有名为的变量a,它无法计算表达式condition + a(在#4),并且失败并出现您看到的错误。


推荐阅读