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> 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
3 Réponses :
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 }
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)
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.
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
#...
Bizarre. Il semble que le problème soit dans
lm code>. Lorsqu'il tente de trouver la fonction de la ligne suivante:
mf <- eval (mf, parent.frame ()) code>
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))} code> suivi avec
IRLS (mlm, wfunc, 0.001) code>
Je ne sais pas ce qui se passe avec
lm code>, mais j'ai eu votre code exécuté en faisant d'abord la définition
wfunc code> dans mon autre commentaire, puis ajoutez une ligne à l'intérieur
IRLS code> qui met les poids à l'intérieur du modèle.
Imodel $ Modèle $ Poids <- wfunc (imodel) code> puis cela a fonctionné.
Voir aussi développeur.r-project.org/nontandard-eval.pdf