Tengo un problema extraño con R que parece que no puedo resolver.Objeto no encontrado error al pasar la fórmula del modelo a otra función
He intentado escribir una función que realiza la validación cruzada K-fold para un modelo elegido por el procedimiento paso a paso en R. (Soy consciente de los problemas con los procedimientos paso a paso, es puramente para fines de comparación) :)
Ahora el problema es que si defino los parámetros de la función (linmod, k, dirección) y ejecuto el contenido de la función, funciona sin problemas. PERO, si lo ejecuto como una función, me sale un error que dice que el objeto datas.train no se puede encontrar.
He intentado recorrer la función con debug() y el objeto existe claramente, pero R dice que no cuando realmente ejecuto la función. Si acabo de encajar un modelo usando lm() funciona bien, entonces creo que es un problema con la función de paso en el ciclo, mientras está dentro de una función. (Intente comentar el comando paso, y establecer las predicciones a los del modelo lineal ordinario.)
#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)
¿Alguna idea?
Parece haber un problema de scoping, donde 'step (lm.1, direction = direction, trace = 0)' no puede encontrar 'datas.train', como ya sabe. No puedo ver la causa del problema yo mismo. Asignar 'datas.train' como una variable global es una solución temporal, pero no particularmente satisfactoria (' datas.train << - datas [-xval.idx [[j]],] '). Quizás esto debería migrarse a StackOverflow? – jthetzel
Específicamente, la llamada a 'add1 (ajuste, alcance $ add, scale = scale, trace = trace, k = k, ...)' en 'step()' arroja el error, donde 'add1()' es ' stats ::: add1.lm'. – jthetzel
@jthetzel, De hecho. Una forma de resolver un problema similar, pero para otra llamada de función dentro de un bucle era asignarlo globalmente. – dcl