r - 在函数内调用 lm() 中的权重无法正确评估
问题描述
我正在编写一个需要加权回归的函数。我一直在使用 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))
这返回
eval 中的错误(extras、data、env):找不到对象“wts”
如果你单独运行这一切,它工作正常。我已经深入研究了 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
帮助页面上的描述中:“公式,子集和...中的所有变量首先在数据中查找,然后在公式环境中查找(有关更多详细信息,请参见公式()的帮助)并收集到一个数据框”。所以它再次查看公式的环境,而不是调用框架。
推荐阅读
- c# - Rijndael托管解密问题
- linux-kernel - 为什么 vm.nr_hugepages 被覆盖?
- mongodb - 如何在 mongodb 中为 mapreduce 函数计时?
- amazon-dynamodb - 如何为 AWS V3 Dynamo 客户端设置超时
- javascript - 尝试导入错误:“css”未从“glamor”导出,即使我已正确导入它
- php - 如何使用 JSON?
- npm - 无法在 Gitlab 上发布私有 npm 包 - E404 Not found PUT
- java - 当我尝试保存 java spring boot @onetomany 关系时,TypeMismatch
- ios - 如何控制单元格重定义
- reactjs - 在屏幕上显示图像之前触发事件?