省略号麻烦:传递给lm [英] Ellipsis Trouble: Passing ... to lm
问题描述
我正在围绕lm
构建包装器,以进行一些其他计算.我希望包装程序将...
传递给lm
,但是我遇到了lm
的weights
参数的麻烦.
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
帮助页面上显示
所有
weights
,subset
和offset
的评估方式与formula
中的变量相同,首先在data
中,然后在formula
环境中.
All of
weights
,subset
andoffset
are evaluated in the same way as variables informula
, that is first indata
and then in the environment offormula
.
但是包装程序似乎改变了一切.
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')
上面的代码并不是最漂亮的,但是它对subset
和weights
都适用.另外,您可以只将weights
和subset
作为例外.
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屋!