2014-12-02 83 views
2

我希望能够在函数内调用lm,并将weights变量指定为传递给外部函数的参数,然后传递给lm。下面是一个可重复使用的示例,其中调用在函数外部调用lm时生效,但在从包装器函数内调用时生成错误消息Error in eval(expr, envir, enclos) : object 'weightvar' not found在R中将参数传递给lm函数

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

当你输入'gear'时,你会得到什么?没有什么,它不是全局定义的,你的'olswrapper'不知道在'df'内部寻找它。让它工作的一种方法是将'weightvar =“gear”'作为一个字符,然后在你的'lm'中调用'weights = df [weightvar]'。 – Gregor 2014-12-03 00:10:57

+0

[R:将参数传递给R函数内部的glm]的可能重复(http://stackoverflow.com/questions/10858318/r-pass-argument-to-glm-inside-an-r-function) – user20650 2014-12-03 00:26:42

回答

2

建立在评论上,gear没有全局定义。它可以在您指定您正在使用的数据的独立呼叫lm内工作,所以lm知道要从df获取gear

不过,gear本身并不存在那个独立的lm功能之外。这是由gear

> gear 
Error: object 'gear' not found 

输出显示可以通过gear到使用df$gear

weightvar <- df$gear 
ols <- olswrapper(mpg ~ cyl + qsec, weightvar , df = df) 
+0

为什么这种行为与将'df $ gear'直接传递给包装器(产生相同的错误)不同? – Michael 2014-12-03 00:27:10

1

我知道我迟到了这个功能,但我相信前面的解释是不完整的。声明weightvar <- df$gear,然后将它传递给该函数仅适用,因为您使用weightvar作为您的weight参数的名称。这只是使用weightvar作为全局变量。这就是为什么df$gear不能直接工作。如果您使用除weightvar以外的任何名称,它也不起作用。

它不起作用的原因是lm在两个地方查找数据:dataframe参数(如果指定)和公式的环境。在这种情况下,您公式的环境是R_GlobalEnv。 (您可以通过从olswrapper内部运行print(str(form))来测试此操作)。因此,lm将只在全球环境和df,而不是功能环境。

编辑:在lm文档中的数据参数的描述表示:在包含该模型中的变量 “可选的数据帧,列表或环境(或对象强制转换由as.data.frame到的数据帧)。 如果未在数据中找到,则变量取自环境(公式),通常是调用lm的环境。“

一个快速的解决方法是说environment(form) <- environment()来改变你的公式的环境。这不会导致任何问题,因为公式中的数据位于您指定的数据框中。