2012-08-02 12 views
8

Tengo un problema con el NLME paquete usando el siguiente código:Uso de predecir de una llamada de función con objetos NLME y una fórmula

library(nlme) 
x <- rnorm(100) 
z <- rep(c("a","b"),each=50) 
y <- rnorm(100) 
test.data <- data.frame(x,y,z) 
test.fun <- function(test.dat) 
{ 
    form <- as.formula("y~x") 
    ran.form <- as.formula("~1|z") 
    modell <- lme(fixed = form, random=ran.form, data=test.dat) 
    pseudo.newdata <- test.dat[1,] 
    predict(modell, newdata= pseudo.newdata) ###THIS CAUSES THE ERROR! 
} 

test.fun(test.data) 

El predicen causas de un error y que ya se encuentran básicamente lo que lo causa.

El objeto modell guarda cómo se llamó y parece que lo usa para hacer predicción, pero no puede encontrar la forma de objetos de fórmula y ejecutar.forma porque no los busca en el espacio de nombres correcto. De hecho, no puedo evitar el problema al hacer esto:

attach(environment(form), warn.conflicts = FALSE) 
predict(modell, newdata= pseudo.newdata) 
detach() 

Mi meta a largo plazo, sin embargo es salvar el modelo agotado en el disco y usarlos más tarde. Supongo que también podría intentar guardar los objetos de la fórmula, pero esto me parece una forma muy molesta e incómoda de lidiar con el problema.

Trabajo con objetos de fórmula generados automáticamente en lugar de escribirlos explícitamente porque creo muchos modelos con diferentes definiciones en un tipo de proceso por lotes, así que no puedo evitarlos. Así que mi solución ideal sería una forma de crear el objeto lme para que luego pueda olvidarme del objeto fórmula y predecir "simplemente funciona". Gracias por cualquier ayuda.

Respuesta

5

Intente reemplazar lme(arg1, arg2, arg3) con do.call(lme, list(arg1, arg2, arg3)).

library(nlme) 
x <- rnorm(100) 
z <- rep(c("a","b"),each=50) 
y <- rnorm(100) 
test.data <- data.frame(x,y,z) 
test.fun <- function(test.dat) 
{ 
    form <- as.formula("y~x") 
    ran.form <- as.formula("~1|z") 
    ## JUST NEED TO CHANGE THE FOLLOWING LINE 
    ## modell <- lme(fixed = form, random=ran.form, data=test.dat) 
    modell <- do.call(lme, list(fixed=form, random=ran.form, data=test.data)) 
    pseudo.newdata <- test.dat[1,] 
    predict(modell, newdata= pseudo.newdata) ###THIS CAUSES THE ERROR! 
} 

test.fun(test.data) 
#   a 
# 0.07547742 
# attr(,"label") 
# [1] "Predicted values" 

Esto funciona porque do.call() evalúa la lista de parámetros en el marco de la llamada, antes evaluar la llamada a lme() que construye. Para ver por qué que ayuda, escriba debug(predict), y luego ejecute su código y el mío, comparando los mensajes de depuración impresos cuando aparece en el navegador.

+1

+1 Buen uso de 'do.call' – Andrie

+0

Brian Ripley me enseñó un truco similar en 2003, usando eval. Como lo he usado con tanta frecuencia, lo hemos llamado "juego de Ripley". http://finzi.psych.upenn.edu/R/Rhelp02a/archive/16599.html –

+1

+1 esto es mucho mejor de lo que había comenzado a piratear, que era algo así como 'modell <- lapply (modell $ call , eval.parent) '(ugh). Es una lástima que esto sea necesario, aunque ... parte del diseño del marco de modelado es (innecesariamente) frágil ... –

Cuestiones relacionadas