我正在编写一个需要加权回归的函数。我反复遇到weights参数错误,并且创建了一个最小的可重现示例,您可以在这里找到:
wt_reg <- function(form, data, wts) {
lm(formula = as.formula(form), data = data,
weights = wts)
}
wt_reg(mpg ~ cyl, data = mtcars, wts = 1:nrow(mtcars))
这返回
Error in eval(extras, data, env) : object 'wts' not found
如果将它们全部单独运行,则可以正常运行。我研究了lm,看来问题是调用了
eval(mf, parent.frame())
。即使wts在parent.frame()中,在调用中似乎也无法正确评估它。这里有一些细节:mf被分配为与
stats::model.frame(formula = as.formula(form), data = data, weights = wts,
drop.unused.levels = TRUE)
当我运行时
parent.frame()$wts
它确实返回一个数值向量。但是当我运行时
eval(stats::model.frame(formula = as.formula(form), data = data, weights = wts,
drop.unused.levels = TRUE), parent.frame())
没有。
我可以跑
stats::model.frame(formula = as.formula(parent.frame()$form),
data = parent.frame()$data, weights = parent.frame()$wts,
drop.unused.levels = TRUE)
它的工作原理。如果您想使用顶部的示例,则可以自己进行测试。
有什么想法吗?我真的不知道这是怎么回事...
最佳答案
R中特殊的公式不仅可以跟踪符号/变量名称,还可以跟踪创建它们的环境。查看
ff <- mpg ~ cyl
environment(ff)
# <environment: R_GlobalEnv>
foo <- function() {
ff <- mpg ~ cyl
environment(ff)
}
foo()
# <environment: 0x0000026172e505d8> private function environment (different each time)
问题在于
lm
将尝试使用创建公式的环境来查找变量,而不是查找父框架。由于您在对wt_reg
的调用中创建了公式,因此该公式将保留在全局范围内。但是wts
仅存在于函数范围内。您可以更改函数以将公式上的环境更改为本地函数环境,然后一切正常wt_reg <- function(form, data, wts) {
ff <- as.formula(form)
environment(ff) <- environment()
lm(formula = ff, data = data,
weights = wts)
}
wt_reg(mpg ~ cyl, data = mtcars, wts = 1:nrow(mtcars))
您在
eval(mf, parent.frame)
中引用的lm()
将使用您的公式调用model.frame()
。并从?model.frame
帮助页面上的描述中:“首先在数据中然后在公式的环境中查找公式,子集和in ...中的所有变量(有关更多详细信息,请参阅help for Formula()),并进行收集放入数据框”。因此,它再次在公式的环境中寻找,而不是在调用框架中寻找。
关于r - 在函数内的lm()中调用权重无法正确评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61164404/