【问题标题】:Passing Argument to lm in R within Function在函数内将参数传递给 R 中的 lm
【发布时间】:2015-01-31 09:31:31
【问题描述】:

我希望能够在函数内调用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"

【问题讨论】:

  • 输入gear 会得到什么?没什么,它不是全局定义的,你的olswrapper 不知道在df 中寻找它。使其工作的一种方法是将weightvar = "gear" 作为字符传递,然后在您的lm 中调用make weights = df[weightvar]

标签: r lm


【解决方案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)

更多: http://adv-r.had.co.nz/Computing-on-the-language.html

【讨论】:

    【解决方案2】:

    我知道我迟到了,但我相信前面的解释是不完整的。声明 weightvar &lt;- df$gear 然后将其传递给函数仅有效,因为您使用 weightvar 作为权重参数的名称。这只是使用weightvar 作为全局变量。这就是df$gear 不能直接工作的原因。如果您使用除weightvar 之外的任何名称,它也不起作用。

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

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

    一个快速的解决方法是说environment(form) &lt;- environment() 来更改公式的环境。这不会造成任何问题,因为公式中的数据在您指定的数据框中。

    【讨论】:

      【解决方案3】:

      在 cmets 的基础上,gear 未在全局范围内定义。当您指定正在使用的数据时,它在独立的 lm 调用中工作,因此 lm 知道从 df 获取 gear

      但是,gear 本身并不存在于独立的 lm 函数之外。 gear的输出显示了这一点

      > gear
      Error: object 'gear' not found
      

      您可以使用df$geargear 传递给函数

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

      【讨论】:

      • 为什么这与将df$gear 直接传递给包装器(产生相同的错误)的行为不同?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 2018-08-05
      • 1970-01-01
      • 2020-03-04
      • 2019-03-29
      相关资源
      最近更新 更多