来自lapply和trycatch

时间:2017-10-17 12:41:43

标签: r try-catch lapply

我试图通过用lapply替换for循环来加速我的代码。我在很多不同的样本上运行nls模型并提取coefs但是有些模型没有收敛到某些样本。我可以通过一个for循环使用trycatch处理这个问题来忽略那些样本,但是我无法让它与lapply一起工作。当我运行这个时,我得到一个sample.code和NULL的列表,我应该在哪里放置return(nls.dat)?部分所以我不会结束NULL?

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

1 个答案:

答案 0 :(得分: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"