9

我正在尝试在 R 中编写一个简单的迭代重新加权最小二乘算法。我想传递一个函数作为计算权重的参数,但不幸的是 R 抱怨找不到该函数。任何想法我做错了什么?提前致谢!

这是我的代码:

irls <- function(imodel, wfunc, tol) {

    repeat {
        b0 <- imodel$coef
        imodel <- lm(formula(imodel), weights=wfunc(imodel), data=imodel$model)
        b1 <- imodel$coef
        if(abs((b1-b0)/b0)<=tol) break
    }

    imodel
}

和一个愚蠢的例子来证明这个问题

x <- 1:100
y <- x + rnorm(100)
mlm <- lm(y~x-1)
irls(mlm, function(x){rep(1,length(x$fit))},0.001) # error: wfunc not found
4

3 回答 3

8

问题在于 lm 如何查找数据。如果您将功能更改为此它似乎可以工作

irls <- function(imodel, wfunc, tol) {

    repeat {
        b0 <- imodel$coef
        dat <- imodel$model
        dat$wts <- wfunc(imodel)
        imodel <- lm(formula(imodel), weights=wts, data=dat)
        b1 <- imodel$coef
        if(abs((b1-b0)/b0)<=tol) break
    }

    imodel
}
于 2013-08-22T15:08:05.703 回答
5

formula包含初始lm调用的环境(在.GlobalEnv本例中为 ),在该环境wfunc中不可用。作为一种解决方法,您可以将其替换为当前环境。

irls <- function(imodel, wfunc, tol) {
  f <- formula(imodel)
  environment(f) <- environment()
  repeat {
    b0 <- imodel$coef
    imodel <- lm(f, weights=wfunc(imodel), data=imodel$model)
    b1 <- imodel$coef
    if(abs((b1-b0)/b0)<=tol) break
  }
  imodel
}
irls(mlm, function(x){rep(1,length(x$fit))},0.001)
于 2013-08-22T15:09:07.143 回答
-1

出现这个问题是因为model.frame.default被称为 inside lm,它评估公式环境中的所有内容:

model.frame.default
#function (formula, data = NULL, subset = NULL, na.action = na.fail, 
#    drop.unused.levels = FALSE, xlev = NULL, ...) 
#{
#...
#    env <- environment(formula)
#...
#    extras <- eval(extras, data, env)  <-- this is where you run into a problem
#...

因此,就像其他人建议的那样,评估lm.

于 2013-08-22T15:11:50.880 回答