2012-08-02 11 views
8

Mam problem z NLME pakiet za pomocą następującego kodu:Korzystanie przewidzieć w wywołaniu funkcji z przedmiotami NLME i formułą

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) 

przewidzieć przyczyny błędu, a ja już znalazłem to, czego w zasadzie go wywołuje.

Obiekt modell zapisuje sposób jego wywoływania i przewiduje, że przewidywania używają go do przewidywania, ale nie może znaleźć formuły obiektów form, a ran.form powoduje, że nie szuka ich we właściwej przestrzeni nazw. W rzeczywistości, można uniknąć tego problemu w ten sposób: jednak

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

Moje długoterminowym celem jest, aby zapisać na dysku modell i wykorzystać je później. Przypuszczam, że mógłbym spróbować zapisać obiekty z formułami, ale to uderza mnie jako bardzo irytujący i uciążliwy sposób radzenia sobie z problemem.

Pracuję z automatycznie generowanymi obiektami formuł, zamiast zapisywać je jawnie, ponieważ tworzę wiele modeli z różnymi definicjami w procesie wsadowym, więc nie mogę ich uniknąć. Moim idealnym rozwiązaniem byłby więc sposób na stworzenie obiektu Lme, aby potem móc zapomnieć o obiekcie formuły i przewidzieć "po prostu działa". Dzięki za pomoc.

Odpowiedz

5

Spróbuj wymienić lme(arg1, arg2, arg3) na 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" 

To działa, ponieważ do.call() ocenia swoją listę argumentów w ramie wywołującego, przed oceny wezwanie do lme() że konstruuje. Aby zobaczyć, dlaczego to pomaga, wpisz, wpisz , a następnie uruchom swój kod i mój, porównując komunikaty debugowania wydrukowane, gdy pojawi się w przeglądarce.

+1

+1 Przyjemne użycie 'do.call' – Andrie

+0

Brian Ripley nauczył mnie podobnej sztuczki w 2003 roku, używając eval. Ponieważ używam go tak często, nazwaliśmy go "grą Ripleya". http://finzi.psych.upenn.edu/R/Rhelp02a/archive/16599.html –

+1

+1 To jest znacznie lepsze niż zacząłem hackować z, co było czymś w rodzaju 'modell <- lapply (modell $ call , eval.parent) '(ugh). Szkoda, że ​​te rzeczy są niezbędne, chociaż ... niektóre z konstrukcji szkieletu modelowania (niepotrzebnie?) Są kruche ... –

Powiązane problemy