2012-08-02 2 views
8

Ich habe ein Problem mit dem Paket NLME mit dem folgenden Code:die Verwendung in einem Funktionsaufruf mit NLME Objekte vorhersagen und eine Formel

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) 

Die Ursachen ein Fehler vorhersagen, und ich fand schon, was es im Grunde verursacht.

Das Modellobjekt speichert, wie es aufgerufen wurde und prognostiziert, scheint das zu nutzen, um Vorhersagen zu machen, aber es ist nicht möglich, die Formelobjekte form und ran.form zu finden, weil es nicht im richtigen Namensraum sucht. In der Tat kann ich das Problem dadurch vermeiden:

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

Mein langfristiges Ziel aber ist es, das Modell auf der Festplatte zu speichern und später zu verwenden. Ich denke, ich könnte versuchen, auch die Formelobjekte zu speichern, aber das erscheint mir als eine sehr nervige und umständliche Art, mit dem Problem umzugehen.

Ich arbeite mit automatisch generierten Formelobjekten, anstatt sie explizit aufzuschreiben, weil ich viele Modelle mit unterschiedlichen Definitionen in einer Art Stapelverarbeitung erzeuge, so dass ich sie nicht vermeiden kann. Also wäre meine ideale Lösung eine Möglichkeit, das lme-Objekt zu erstellen, so dass ich das Formelobjekt im Nachhinein vergessen und vorhersagen kann "funktioniert einfach". Danke für jede Hilfe.

Antwort

5

Versuchen Sie, lme(arg1, arg2, arg3) durch do.call(lme, list(arg1, arg2, arg3)) zu ersetzen.

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" 

Das funktioniert, weil do.call() seine Argumentliste in dem anrufenden Rahmen auswertet, vor den Anruf zu lme() Auswertung, die sie konstruiert. Um zu sehen, warum , dass hilft, geben Sie debug(predict), und führen Sie dann Ihren Code und mir, Vergleichen der Debugging-Nachrichten gedruckt, wenn Sie in den Browser popped sind.

+1

+1 Schöne Verwendung von 'do.call' – Andrie

+0

Brian Ripley lehrte mich einen ähnlichen Trick im Jahr 2003 mit Eval. Da ich es so oft benutzt habe, haben wir es "Ripleys Spiel" genannt. http://finzi.psych.upenn.edu/R/Rhelp02a/archive/16599.html –

+1

+1 das ist viel besser als ich anfing, herumzuhacken, das war etwas wie 'modell <- lapply (modell $ call , eval.parent) '(hu). Es ist schade, dass dieses Zeug notwendig ist, obwohl ... ein Teil des Designs des Modeling-Frameworks (unnötig ??) zerbrechlich ist ... –

Verwandte Themen