2017-10-17 108 views
0

我試圖通過更換與lapply循環加快我的代碼。我在很多不同的樣本上運行nls模型,並提取係數,但有些模型不適合某些樣本。我可以用trycatch的for循環來處理這個問題,以忽略這些樣本,但我無法讓它與lapply一起工作。當我運行這個時,我得到了我的sample.code和NULL的列表,我應該在哪裏放置return(nls.dat)?部分,所以我不只是結束NULL?NULL輸出和trycatch

test.func <- function (SCDF){ 
    tryCatch({ 
    mod.allDIDO <- nlsLM (BM~Cr*(1 - R * exp(-Kr*day) - (1 - R) * exp(-Kr2*day)), data=dat[dat$sample.code %in% SC,], start=list(Cr=DI.Cr,R=DI.r,Kr=DI.Kr,Kr2=DI.Kr2), 
         control = nls.lm.control(maxiter = 500), lower = c(-Inf, 0, 0, 0), upper = c(Inf, 1, Inf, Inf)) 
    nls.dat <- c("df", coef(mod.allDIDO)[1], coef(mod.allDIDO)[2], coef(mod.allDIDO)[3], coef(mod.allDIDO)[4], deviance(mod.allDIDO), logLik(mod.allDIDO)) 
    return (nls.dat) 
    }, error = function(e){}) 
} 

test1 <- lapply(split(dat, dat$sample.code), test.func) 

編輯,包括一些數據和回覆卡爾: 我想你的建議(卡爾),但我仍然得到NULL,請參閱版本

x1 <- 0:60 
y1 <- 774*(1 - 0.5 * exp(-0.2*x1) - (1 - 0.5) * exp(-0.016*x1)) 
test.dat <- data.frame (x1, y1) 

    nls.dat <- tryCatch({ 
    mod.allDIDO <- nlsLM(y1~Cr*(1 - R * exp(-Kr*x1) - (1 - R) * exp(-Kr2*x1)), 
         data=test.dat, 
         start=list(Cr=774,R=0.5,Kr=0.2,Kr2=0.016), 
         control = nls.lm.control(maxiter = 500), 
         lower = c(-Inf, 0, 0, 0), 
         upper = c(Inf, 1, Inf, Inf)) 
    nls.dat <- c("df", coef(mod.allDIDO)[1], 
       coef(mod.allDIDO)[2], 
       coef(mod.allDIDO)[3], 
       coef(mod.allDIDO)[4], 
       deviance(mod.allDIDO), 
       logLik(mod.allDIDO)) 
    return(nls.dat) 
    }, error = function(e){}) 

    nls.dat ## NULL 

回答

0

砍下要注意的事情是你呼叫環境。在tryCatch括號內,將包含的呼叫視爲自己的功能。所以,你需要的tryCatch的retuirn返回到父環境,然後從函數返回,就像這樣:

test.func <- function (SCDF){ 
    nls.dat <- tryCatch({ 
    mod.allDIDO <- nlsLM(BM~Cr*(1 - R * exp(-Kr*day) - (1 - R) * exp(-Kr2*day)), 
         data=dat[dat$sample.code %in% SC,], 
         start=list(Cr=DI.Cr,R=DI.r,Kr=DI.Kr,Kr2=DI.Kr2), 
         control = nls.lm.control(maxiter = 500), 
         lower = c(-Inf, 0, 0, 0), 
         upper = c(Inf, 1, Inf, Inf)) 

    nls.dat <- c("df", coef(mod.allDIDO)[1], 
       coef(mod.allDIDO)[2], 
       coef(mod.allDIDO)[3], 
       coef(mod.allDIDO)[4], 
       deviance(mod.allDIDO), 
       logLik(mod.allDIDO)) 
    return(nls.dat) 
    }, error = function(e){ 
    NULL 
    }) 
    return(nls.dat) 
} 

編輯

這是奇怪的現象,所以,我測試了另一種方式,我會從來沒有這樣做,而是爲了某種原因,它的工作原理... 新功能需要的變量,並增加了一個if語句添加另一個......看似不必要的邏輯檢查..但它的工作原理。檢查該值爲NULL,如果沒有回報,如果有錯誤的兩個步驟的任何地方......它會默認爲error = function(e) {NULL}

f <- function(x1, y1, test.dat){ 
    tryCatch({ 
     mod.allDIDO <- nlsLM(y1~Cr*(1 - R * exp(-Kr*x1) - (1 - R) * exp(-Kr2*x1)), 
         data=test.dat, 
         start=list(Cr=774,R=0.5,Kr=0.2,Kr2=0.016), 
         control = nls.lm.control(maxiter = 500), 
         lower = c(-Inf, 0, 0, 0), 
         upper = c(Inf, 1, Inf, Inf)) 
    nls.dat <- c("df", coef(mod.allDIDO)[1], 
       coef(mod.allDIDO)[2], 
       coef(mod.allDIDO)[3], 
       coef(mod.allDIDO)[4], 
       deviance(mod.allDIDO), 
       logLik(mod.allDIDO)) 
    if(!is.null(nls.dat)){ 
     return(nls.dat) 
    }else { 
     NULL 
    } 
}, error = function(e){NULL}) 
} 

和運行...

> f(x1 = x1, y1 = y1, test.dat = test.dat) 
      Cr  R  Kr  Kr2     
    "df" "774" "0.5" "0.2" "0.016"  "0" "Inf" 
+0

喜卡爾,我嘗試了你的建議,但輸出仍爲NULL,請參閱編輯問題中的削減版本和一些數據。上面的作品 – chris20

+0

後編輯...感謝您的數據。如果你包含你正在使用的包,那麼也很有幫助,可以追蹤'minpack.lm'。不知道爲什麼邏輯重複是有幫助的......但它有效。 –

+0

謝謝卡爾,這個作品很棒,對不起,我忘了添加包。 – chris20