我希望能够在函数内调用lm
并将weights
变量指定为传递给外部函数的参数,然后传递给lm
。下面是一个可重现的示例,如果调用在函数外部lm
,则调用有效,但在包装函数内调用时会生成错误消息Error in eval(expr, envir, enclos) : object 'weightvar' not found
。
olswrapper <- function(form, weightvar, df){
ols <- lm(formula(form), weights = weightvar, data = df)
}
df <- mtcars
ols <- lm(mpg ~ cyl + qsec, weights = gear, data = df)
summary(ols)
ols2 <- olswrapper(mpg ~ cyl + qsec, weightvar = gear, df = df)
#Produces error: "Error in eval(expr, envir, enclos) : object 'weightvar' not found"
答案 0 :(得分:2)
在评论的基础上,gear
并未在全球范围内定义。当您指定所使用的数据时,它可以在独立的lm
调用内部使用,因此lm
知道从gear
获取df
。
但是,gear
本身并不存在于独立的lm
函数之外。这由gear
> gear
Error: object 'gear' not found
您可以使用gear
df$gear
传递给该函数
weightvar <- df$gear
ols <- olswrapper(mpg ~ cyl + qsec, weightvar , df = df)
答案 1 :(得分:2)
我知道我迟到了,但我相信之前的解释是不完整的。声明weightvar <- df$gear
然后将其传递给函数只会起作用,因为您使用weightvar
作为权重参数的名称。这只是使用weightvar
作为全局变量。这就是为什么df$gear
不起作用的原因。如果您使用除weightvar
之外的任何名称,它也不起作用。
它不起作用的原因是lm在两个地方查找数据:dataframe参数(如果指定)和公式的环境。在这种情况下,公式的环境为R_GlobalEnv
。 (您可以通过从print(str(form))
内部运行olswrapper
来测试此问题。因此,lm
只会查看全局环境和df
,而不是函数环境。
编辑:在lm
文档中,数据参数的描述说:
“包含模型中变量的可选数据框,列表或环境(或由as.data.frame强制转换为数据框的对象)。如果在数据中找不到,则变量取自环境(公式)< / strong>,通常是调用lm的环境。“
快速解决方法是说environment(form) <- environment()
更改公式的环境。这不会导致任何问题,因为公式中的数据位于您指定的数据框中。
答案 2 :(得分:1)
eval(substitute(...))
使我们可以采用非标准评估
df <- mtcars
olswrapper <- function(form, weightvar, df)
eval(substitute(ols <- lm(formula(form), weights = weightvar, data = df)))
summary(ols)
olswrapper(mpg ~ cyl + qsec, weightvar = gear, df = df)