2013-08-22 20 views
8

Sto provando a scrivere un semplice algoritmo dei minimi quadrati iterativo reimpostato in R. Voglio passare una funzione come argomento per il calcolo dei pesi, ma purtroppo R si lamenta che la funzione non può Essere trovato. Qualche idea su cosa sto facendo male? Grazie in anticipo!R: funzione passata come argomento non trovata

Ecco il mio codice:

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 
} 

e un esempio stupido per dimostrare il problema

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

Strano. Sembra che il problema sia in 'lm'. Quando cerca di trovare la funzione nella seguente riga: 'mf <- eval (mf, parent.frame())' – nograpes

+0

Può aiutare: http://stackoverflow.com/questions/7027288/error-could-not- find-function-in-r – Fernando

+1

Penso che sia meglio definire prima la funzione. 'wfunc <-function (x) {rep (1, length (x $ fit))}' seguito da 'irls (mlm, wfunc, 0.001)' –

risposta

8

Il problema si presenta con quanto lm guarda per i dati. Se si cambia la funzione per questo sembra funzionare

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

Dang mi hai ninja! –

+0

Grazie mille :) – linuxfever

5

Il formula contiene l'ambiente del lm chiamata iniziale (.GlobalEnv, in questo caso), in cui wfunc non era disponibile. Come soluzione alternativa, è possibile sostituirlo con l'ambiente corrente.

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

Hai solo bisogno di farlo una volta - non ogni volta. – hadley

+0

@hadley: buon punto. Ho spostato la formula all'esterno del ciclo. –

-1

Questo problema si pone perché model.frame.default si chiama all'interno lm, che valuta tutto l'ambiente della formula:

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 
#... 

Così come gli altri hanno suggerito, valutare la funzione al di fuori di lm.

+0

e il motivo del downvote è ... – eddi

Problemi correlati