省略号麻烦:传递给lm [英] Ellipsis Trouble: Passing ... to lm

查看:109
本文介绍了省略号麻烦:传递给lm的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在围绕lm构建包装器,以进行一些其他计算.我希望包装程序将...传递给lm,但是我遇到了lmweights参数的麻烦.

I am building a wrapper around lm to do some additional calculations. I'd like the wrapper to pass ... to lm, but I am getting into trouble with lm's weights argument.

LmWrapper <- function(df, fmla, ...) {
  est <- lm(fmla, df, ...)
  list(model = est)
}

如果我用weights参数调用包装器,

If I call the wrapper with a weights argument,

data(airquality)
LmWrapper(airquality, Ozone ~ Wind, weights = Temp)

R不知道在哪里寻找权重:

R does not know where to look for the weights:

Error in eval(expr, envir, enclos) : 
  ..1 used in an incorrect context, no ... to look in

lm帮助页面上显示

所有weightssubsetoffset的评估方式与formula中的变量相同,首先在data中,然后在formula环境中.

All of weights, subset and offset are evaluated in the same way as variables in formula, that is first in data and then in the environment of formula.

但是包装程序似乎改变了一切.

but the wrapper seems to change things.

我该如何解决?

上述错误的traceback()看起来像这样:

The traceback() for the above error looks like this:

8: eval(expr, envir, enclos)
7: eval(extras, data, env)
6: model.frame.default(formula = fmla, data = df, weights = ..1, 
       drop.unused.levels = TRUE)
5: stats::model.frame(formula = fmla, data = df, weights = ..1, 
       drop.unused.levels = TRUE)
4: eval(expr, envir, enclos)
3: eval(mf, parent.frame())
2: lm(fmla, df, ...) at #2
1: LmWrapper(diamonds, price ~ carat, weights = depth)

直接调用lm,效果很好:

lm(Ozone ~ Wind, airquality, weights = Temp)

推荐答案

因此,问题在于lm通常在参数数据中查找这些名称,但范围界定却以某种方式出了问题.您可以通过查找列引用并将其手动传递来解决此问题.

So the problem is that lm normally looks up those names in argument data but somehow scoping goes wrong. You can fix that by looking up column references and passing them on manually.

LmWrapper <- function(df, fmla, ...) {
  # get names of stuff in ...
  argNames = sapply(substitute(list(...))[-1L], deparse)
  # look for identical names in df
  m = match(names(df), argNames, 0L)
  # store other arguments from ... in a list
  args = list(eval(parse(text = argNames[-m])))
  # name the list
  names(args) = names(argNames[-m])
  # store complete values in args, instead of just references to columns
  # the unlist code is rather ugly, the goal is to create a list where every
  # element is a column of interest
  args[names(argNames)[m]] = unlist(apply(df[, as.logical(m), drop = FALSE], 
                                       2, list), recursive = FALSE)
  # also put other stuff in there
  args$formula = fmla
  args$data = df
  # do lm
  est = do.call(lm, args)
  list(model = est)
}

data(airquality)

airquality$subset = airquality$Solar.R > 200
LmWrapper(airquality, Ozone ~ Wind, weights = Temp, subset = subset, 
          method = 'qr')

上面的代码并不是最漂亮的,但是它对subsetweights都适用.另外,您可以只将weightssubset作为例外.

The code above is not the most beautiful, but it works for both subset and weights. Alternatively, you could just handle weights and subset as exceptions.

这篇关于省略号麻烦:传递给lm的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆