9
votes

R: La fonction passée comme argument n'est pas trouvée

J'essaie d'écrire un algorithme de moindres carrés itératif itératif simple dans R. Je souhaite transmettre une fonction comme argument pour le calcul des poids, mais malheureusement, se plaint que la fonction ne peut pas être trouvée. Des idées ce que je fais mal? Merci d'avance!

Voici mon code: p> xxx pré>

et un exemple idiot pour démontrer le problème P>

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


5 commentaires

Bizarre. Il semble que le problème soit dans lm . Lorsqu'il tente de trouver la fonction de la ligne suivante: mf <- eval (mf, parent.frame ())


Il peut aider: Stackoverflow.com / Questions / 7027288 / ...


Je pense que vous feriez mieux de définir votre fonction en premier. wfunc <-function (x) {rep (1, longueur (x $ ajustement))} suivi avec IRLS (mlm, wfunc, 0.001)


Je ne sais pas ce qui se passe avec lm , mais j'ai eu votre code exécuté en faisant d'abord la définition wfunc dans mon autre commentaire, puis ajoutez une ligne à l'intérieur IRLS qui met les poids à l'intérieur du modèle. Imodel $ Modèle $ Poids <- wfunc (imodel) puis cela a fonctionné.


Voir aussi développeur.r-project.org/nontandard-eval.pdf


3 Réponses :


8
votes

Le problème apparaît avec la recherche des données LM. Si vous modifiez la fonction à ceci, il semble fonctionner

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
}


0 commentaires

5
votes

Le formule code> contient l'environnement de l'appel initial lm code> ( .globalenv code>, dans ce cas), dans lequel wfunc code> n'était pas disponible. En tant que contournement, vous pouvez le remplacer par l'environnement actuel.

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)


2 commentaires

Vous n'avez besoin que de le faire une fois - pas à chaque fois.


@hadley: Bon point. J'ai déplacé la formule en dehors de la boucle.



-1
votes

Ce problème se pose car modèle.frame.default est appelé inside lm code>, qui évalue tout dans l'environnement de la formule:

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


0 commentaires