L'objet ne trouve pas d'erreur lors du passage de modèle de la formule à une autre fonction
J'ai un problème bizarre avec R que je n'arrive pas à travailler.
J'ai essayé d'écrire une fonction qui effectue la K-fold cross validation d'un modèle choisi par la procédure pas à pas, dans l'arrêt R. (je suis conscient des problèmes avec la progressive des procédures, c'est purement à des fins de comparaison) 🙂
Maintenant la question est, que si j'définir les paramètres de la fonction (linmod,k,direction) et d'exécuter le contenu de la fonction, il fonctionne parfaitement. MAIS, si je le lance en tant que fonction, j'obtiens un message d'erreur indiquant que les données.le train de l'objet ne peut pas être trouvé.
J'ai essayé de marcher à travers la fonction de débogage() et que l'objet existe à l'évidence, mais R dit qu'il ne la pas quand je fait de l'exécution de la fonction. Si je viens de l'ajustement d'un modèle à l'aide de lm (), qui fonctionne bien, donc je crois que c'est un problème avec la fonction step dans la boucle, tandis que l'intérieur d'une fonction. (essayez de commenter la commande de l'étape, et de définir les prédictions de ceux de l'ordinaire du modèle linéaire.)
#CREATE A LINEAR MODEL TO TEST FUNCTION
lm.cars <- lm(mpg~.,data=mtcars,x=TRUE,y=TRUE)
#THE FUNCTION
cv.step <- function(linmod,k=10,direction="both"){
response <- linmod$y
dmatrix <- linmod$x
n <- length(response)
datas <- linmod$model
form <- formula(linmod$call)
# generate indices for cross validation
rar <- n/k
xval.idx <- list()
s <- sample(1:n, n) # permutation of 1:n
for (i in 1:k) {
xval.idx[[i]] <- s[(ceiling(rar*(i-1))+1):(ceiling(rar*i))]
}
#error calculation
errors <- R2 <- 0
for (j in 1:k){
datas.test <- datas[xval.idx[[j]],]
datas.train <- datas[-xval.idx[[j]],]
test.idx <- xval.idx[[j]]
#THE MODELS+
lm.1 <- lm(form,data= datas.train)
lm.step <- step(lm.1,direction=direction,trace=0)
step.pred <- predict(lm.step,newdata= datas.test)
step.error <- sum((step.pred-response[test.idx])^2)
errors[j] <- step.error/length(response[test.idx])
SS.tot <- sum((response[test.idx] - mean(response[test.idx]))^2)
R2[j] <- 1 - step.error/SS.tot
}
CVerror <- sum(errors)/k
CV.R2 <- sum(R2)/k
res <- list()
res$CV.error <- CVerror
res$CV.R2 <- CV.R2
return(res)
}
#TESTING OUT THE FUNCTION
cv.step(lm.cars)
Toutes les pensées?
- Il semble y avoir un problème d'étendue, où
step(lm.1,direction=direction,trace=0)
ne peut pas trouverdatas.train
, comme vous le savez déjà. Je ne vois pas le problème moi-même. L'attributiondatas.train
comme une variable globale est une solution, mais pas particulièrement satisfaisante de l' (datas.train <<- datas[-xval.idx[[j]],]
). Peut-être cela devrait être migré vers StackOverflow? - Plus précisément, l'appel à
add1(fit, scope$add, scale = scale, trace = trace, k = k, ...)
dansstep()
jette l'erreur, oùadd1()
eststats:::add1.lm
. - En effet. Une façon, j'ai résolu un problème similaire mais pour un autre appel de fonction à l'intérieur d'une boucle a été d'attribuer à l'échelle mondiale.
Vous devez vous connecter pour publier un commentaire.
Lorsque vous avez créé votre formule,
lm.cars
, en a été affectée à son propre environnement. Cet environnement reste avec la formule, sauf si vous explicitement le changer. Ainsi, lorsque vous extrayez la formule avec lesformula
fonction de l'environnement d'origine du modèle est inclus.Je ne sais pas si je suis en utilisant la terminologie appropriée ici, mais je pense que vous devez explicitement le changement de l'environnement pour la formule à l'intérieur de votre fonction:
Un autre problème qui peut provoquer ce est que si on passe un
character
(stringvector
) àlm
au lieu d'unformula
.vector
s ont pasenvironment
, et donc quandlm
convertit lecharacter
à unformula
, apparemment, il n'a pas deenvironment
au lieu d'être automatiquement attribuée à l'environnement local. Si on utilise alors un objet de poids qui n'est pas dans les données argumentdata.frame
, mais il est dans les locaux de la fonction d'argument, on obtient unnot found
erreur. Ce comportement n'est pas très facile à comprendre. C'est probablement un bug.Voici une minime reproductible exemple. Cette fonction prend un
data.frame
, deux noms de variable et d'un vecteur de poids à utiliser.Et de test:
C'est un très bug subtil. Si on va dans la fonction de l'environnement avec
browser
, on peut voir le poids vecteur très bien, mais de toute façon il n'est pas trouvé dans lelm
appel!Le bug devient encore plus difficile à déboguer si on a utilisé le nom
weights
pour les poids variable. Dans ce cas, puisquelm
ne pouvez pas trouver le poids de l'objet, il prend par défaut la fonctionweights()
de base jetant ainsi un même étranger erreur:Ne me demandez pas combien d'heures il m'a fallu pour comprendre cela.