【问题标题】:NULL output from lapply and trycatchlapply 和 trycatch 的 NULL 输出
【发布时间】:2017-10-17 12:41:43
【问题描述】:

我正在尝试通过用 lapply 替换 for 循环来加速我的代码。我在许多不同的样本上运行 nls 模型并提取系数,但某些模型对于某些样本没有收敛。我可以使用带有 trycatch 的 for 循环来处理这个问题,以忽略这些样本,但我无法让它与 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)

已编辑以包含一些数据并回复 Carl: 我尝试了你的建议(Carl),但我仍然得到 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

【问题讨论】:

    标签: r try-catch lapply


    【解决方案1】:

    要注意的是你的调用环境。在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" 
    

    【讨论】:

    • 嗨,卡尔,我尝试了您的建议,但输出仍然为 NULL,请参阅已编辑问题中的精简版本和一些数据。
    • 以上作品后期编辑...感谢您的数据。如果您包含您正在使用的软件包也很有帮助..必须追捕minpack.lm。不知道为什么合乎逻辑的重复是有帮助的......但它有效。
    • 感谢 Carl,这很好用,抱歉我忘记添加包了。
    猜你喜欢
    • 2019-03-01
    • 1970-01-01
    • 2017-04-10
    • 2012-07-31
    • 2021-12-03
    • 2018-09-01
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    相关资源
    最近更新 更多