我正在阅读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)
然后我收到以下错误消息:
eval(substitute(condition),df)中的错误:找不到对象'a'
我阅读了以下说明,但不太了解:
如果eval()在数据框内(第二个参数)找不到该变量,则它将在subset2()的环境中查找。显然这不是我们想要的,因此我们需要某种方法来告诉eval()如果找不到数据框中的变量,该在哪里查看。
我认为,尽管“ eval(substitute(condition),df)”却找不到条件变量,那么为什么找不到对象“ 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)
答案 0 :(得分:2)
这个更精简的示例可能使您更容易了解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 + a
处#4
的右侧部分)中的符号。来自R语言定义的Section 4.3.3 Argument Evaluation:
关于函数参数评估的最重要的事情之一就是对提供的参数和默认参数的处理方式有所不同。提供给函数的参数在调用函数的求值框架中求值。函数的默认参数在函数的评估框架中评估。
在上面的示例中,对f()
的调用的评估框架是全局环境.GlobalEnv
。
逐步进行,这是您致电(condition = condition + a)
时发生的情况。在函数求值期间,R在函数体中(在condition + a
处遇到表达式#2
。它搜索a
和condition
的值,并找到本地分配的符号a
。它发现符号condition
已绑定到名为condition
的形式参数(在#1
处)。在函数调用期间提供的 that 形式参数的值为condition + a
(在#4
处)。
如R语言定义中所述,表达式condition + a
中符号的值是在调用函数的环境(这里是全局环境)中搜索的。由于全局环境包含名为condition
的变量(在#3
处分配),但是没有名为a
的变量,因此它无法计算表达式condition + a
(在{{1}处) }),并因您看到的错误而失败。
答案 1 :(得分:0)
我想添加一些详细信息,以防有人偶然发现此问题。有问题的行是
condition_call = eval(substitute(condition),df )
替代()函数中的条件对象是一个promise对象,其表达式槽为“一个<条件”,而alternate(condition)接受表达式并返回带有表达式的调用对象为“一个<条件”。
然后,eval()函数开始在df环境中评估“ a <条件”。其目标是同时找到 a 和条件。
在这里总结问题:
对于我的第二个示例,R无法在执行环境中找到y,然后在subset2()的调用环境中将y查找为4,因此不会产生任何错误。在这种情况下,y的名称与承诺对象 condition 不同,并且R不会尝试评估“ a