2016-09-30 113 views
3

我開始編寫一個函數,它可以與nlme建立線性混合模型。我遇到一個錯誤:Error in eval(expr, envir, enclos) : object 'value' not found,我認爲這是由於R不知道在哪裏找到數據幀變量(例如,value)。如果這實際上是錯誤發生的原因,那麼我如何知道valuetimepoint屬於Dat中變量(在下面的可重現代碼中)的函數?lme模型的用戶定義函數擬合:錯誤

require(nlme) 
Dat <- data.frame(
    id = sample(10:19), 
    Time = sample(c("one", "two"), 10, replace = T), 
    Value = sample(1:10) 
) 
nlme_rct_lmm <- function (data, value, timepoint, 
         ID) { 

    #base_level intercept only model 
    bl_int_only <- gls(value ~ 1, 
         data = data, 
         method = "ML", 
         na.action="na.omit")   
    #vary intercept across participants 
    randomIntercept <- lme(value ~ 1, 
          data = data, 
          random = ~1|ID, 
          method = "ML", 
          na.action = "na.omit")  
    #add timepoint as a fixed effect 
    timeFE <- lme(value ~ timepoint, 
        data = data, 
        random = ~1|ID, 
        method = "ML", 
        na.action = "na.omit") 
} 
nlme_rct_lmm(Dat, Value, Time, id) 

回答

3

這不是(正如你我所預料的)在不同的框架內進行評估的問題;相反,這是公式和數據之間的變量名稱之間的一致性問題。 R是大小寫敏感的,所以它的事項是否使用valueValue,或idID等。此外,式解釋使用非標準評價(NSE),因此,如果你有一個可變value等於符號Valuevalue ~ 1是否不是神奇地變成Value ~ 1。我在下面概述的方法是將名稱的響應,時間和ID變量傳遞給函數,因爲這是最簡單的方法。如果使用非標準評估,對最終用戶來說會更優雅一些,但編程有點難(因此理解,調試等)。

下面容易/愚蠢的做法,我還討論瞭如何落實NSE的方法(滾動一路下來...)

請注意,您的例子並不返回任何東西;與R,這意味着所有的結果將完成該功能時將被丟棄。您可能想要將結果作爲列表返回(或者您的實際功能可能會對擬合模型執行其他操作,例如一系列模型測試,然後將結果作爲結果返回...)

require(nlme) 

Dat <- data.frame(
    ID = sample(10:19), 
    Time = sample(c("one", "two"), 10, replace = T), 
    Value = sample(1:10) 
) 

nlme_rct_lmm <- function (data, value, timepoint, 
         ID) { 

    nullmodel <- reformulate("1",response=value) 
    fullmodel <- reformulate(c("1",timepoint),response=value) 
    remodel <- reformulate(paste("1",ID,sep="|")) 

    #base_level intercept only model 
    bl_int_only <- gls(nullmodel, 
         data = data, 
         method = "ML", 
         na.action="na.omit") 

    #vary intercept across participants 
    randomIntercept <- lme(nullmodel, 
          data = data, 
          random = remodel, 
          method = "ML", 
          na.action = "na.omit") 

    #add timepoint as a fixed effect 
    timeFE <- lme(fullmodel, 
        data = data, 
        random = remodel, 
        method = "ML", 
        na.action = "na.omit") 
} 

nlme_rct_lmm(Dat, "Value", "Time", "ID") 

如果你想要一些更優雅(但內部模糊)的東西,你可以用下面幾行代替模型。內部substitute()調用檢索作爲參數傳遞給該函數的符號;外部substitute()調用將這些符號插入到公式中。

nullmodel <- formula(substitute(v~1,list(v=substitute(value)))) 
fullmodel <- formula(substitute(v~t,list(v=substitute(value), 
           t=substitute(timepoint)))) 
remodel <- formula(substitute(~1|i,list(i=substitute(ID)))) 

現在這樣的工作,而不指定變量字符串,如你預期:nlme_rct_lmm(Dat, Value, Time, ID)

+0

這發生在我身上,但我認爲這可能是OP的例子僅僅是個開始(例如,他們可能在返回摘要值之前用結果做其他一些事情);無論如何,在答案中值得一提... –

+0

優秀!是的,實際功能正在返回一系列模型測試。如前所述,我發現NSE方法更符合最終用戶的需求。 –

相關問題