2012-08-02 34 views
8

我有一個用下面的代碼包NLME一個問題:使用預測與NLME對象函數調用和公式

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) 

的預測會導致錯誤,我已經找到了基本原因造成的。

modell對象保存了它的調用方式,預測似乎使用它來進行預測,但無法找到公式對象窗體和ran.form,因爲它沒有在正確的命名空間中查找它們。其實,我可以這樣避免此問題:但是

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

我的長期目標是拯救潛行到磁盤,在以後使用它們。我想我也可以嘗試保存公式對象,但是這使我感到非常煩人和麻煩,以解決這個問題。

我使用自動生成的公式對象,而不是明確地寫下來,因爲我在一種批處理過程中創建了許多具有不同定義的模型,所以我無法避免它們。所以我的理想解決方案是創建lme對象的方法,以便我可以在事後忘記公式對象並預測「正常工作」。謝謝你的幫助。

回答

5

嘗試用do.call(lme, list(arg1, arg2, arg3))代替lme(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" 

這工作,因爲do.call()評估在調用框架參數列表,以前評估呼叫lme()它構造。要明白爲什麼有幫助,請輸入debug(predict),然後運行您的代碼和我的代碼,比較當您彈出到瀏覽器時打印的調試消息。

+1

+1很好的使用'do.call' – Andrie 2012-08-02 15:01:24

+0

Brian Ripley在2003年使用eval教會了我一個類似的技巧。由於我經常使用它,因此我們將其命名爲「Ripley的遊戲」。 http://finzi.psych.upenn.edu/R/Rhelp02a/archive/16599.html – 2012-08-02 15:22:06

+1

+1這比我剛開始討論的要好得多,就像'modell < - lapply(modell $ call) ,eval.parent)'(呃)。這太糟糕了,這個東西是必要的,但是......建模框架的一些設計是(不必要的)脆弱...... – 2012-08-02 16:15:02