2013-08-22 24 views
8

我想在R中編寫一個簡單的迭代重新加權最小二乘算法。我想傳遞一個函數作爲權重計算的參數,但不幸的是,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 
+1

奇怪。看來問題出現在'lm'中。當它試圖找到以下行中的函數:'mf < - eval(mf,parent.frame())' – nograpes

+0

它可能有所幫助:http://stackoverflow.com/questions/7027288/error-could-not- find-function-in-r – Fernando

+1

我認爲你最好先定義你的函數。 ''wfunc <-function(x){rep(1,length(x $ fit))}'後跟'irls(mlm,wfunc,0.001)' –

回答

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 
} 
+1

當你忍住我! –

+0

非常感謝:) – linuxfever

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) 
+0

你只需要做一次 - 不是每一次。 – hadley

+0

@hadley:好點。我已將該公式移至循環之外。 –

-1

這個問題的產生是因爲model.frame.default被稱爲內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之外的功能。

+0

和downvote的原因是... – eddi