【问题标题】:Skip Line if Error Occurs within Function in R如果在 R 中的函数内发生错误,则跳过行
【发布时间】:2020-12-19 11:38:17
【问题描述】:

我目前正在尝试解决一个错误,但我认为我正在处理的数据可能过于复杂并导致通常不应该发生的错误。我编写了一个函数,并希望添加一个trytryCatch 语句以在发生错误时跳过该错误。我目前有:

library(glmnet)
foo <- function(data, ols_ps = TRUE, index) {
  # index is the bootstrap sample index
  x <- data[index, -1]
  y <- data[index, 1]
  ridge <- cv.glmnet(x, y, alpha = 0)
  ## The intercept estimate should be dropped.
  weights <- as.numeric(coef(ridge, s = ridge$lambda.min))[-1]
  # alpha=1, lasso
  alasso <- cv.glmnet(x, y, alpha = 1,
                      penalty.factor = 1 / abs(weights))
  # Select nonzero coefficients
  coef <- as.vector(coef(alasso, s = alasso$lambda.min, 
                         exact = TRUE, x = x, y = y,
                         penalty.factor = 1 / abs(weights)))[-1]
  if (ols_ps == TRUE) {
    coef_nonzero <- coef != 0
    new_x <- tryCatch(x[, coef_nonzero, drop = FALSE], 
                      error=function(e) NA)
    if (!any(is.na(new_x)) & ncol(new_x) > 0) {
      ls.obj <- lm(y ~ new_x)
      ls_coef <- (ls.obj$coefficients)[-1]
      coef[coef_nonzero] <- ls_coef
    } else {
      coef <- coef
    }
  } else {
    coef <- coef
  }
  return(coef)
}

这通常适用于大多数数据集。我认为错误可能来自复杂的数据集。如果出现以下错误,是否可以跳过 OLS?

"x[, coef_nonzero, drop = FALSE] 中的错误:\n (下标) 逻辑下标太长\n" attr(,"类")

这是每个请求的最小工作示例。

set.seed(123)
matrix <- matrix(runif(1000), ncol=10)
boot(matrix,foo,R=50)

提前致谢。

【问题讨论】:

  • 错误是length(coef_nonzero) &gt; ncol(x)
  • 能否提供一个可运行的使用示例?
  • @Oliver 我想了这么多,但不太明白如果coef_nonzero 来自glmnet 的非零系数,这怎么可能。
  • @jay.sf 我已经用一个例子编辑了上面的内容,但是不会出错。我认为错误来自一个我无法重现自己的复杂数据集
  • 我建议用这样的例子来调试你的代码。如果没有可重现的示例,很难提出建议的编辑。如果这对您来说是新的,data-flair 有一个用于调试 R 代码的可视化指南。 :-)

标签: r try-catch


【解决方案1】:

可能是这样的?

foo <- function(data, index) {
  # index is the bootstrap sample index
  x <- data[index, -1]
  y <- data[index, 1]
  ridge <- cv.glmnet(x, y, alpha = 0)
  ## The intercept estimate should be dropped.
  weights <- as.numeric(coef(ridge, s = ridge$lambda.min))[-1]
  # alpha=1, lasso
  alasso <- cv.glmnet(x, y, alpha = 1,
                      penalty.factor = 1 / abs(weights))
  # Select nonzero coefficients
  coef <- as.vector(coef(alasso, s = alasso$lambda.min, 
                         exact = TRUE, x = x, y = y,
                         penalty.factor = 1 / abs(weights)))[-1]
  coef_nonzero <- coef != 0
  new_x <- tryCatch(x[, coef_nonzero, drop = FALSE], 
                    error=function(e) NA)
  if (!any(is.na(new_x))) {
    ls.obj <- lm(y ~ new_x)
    ls_coef <- (ls.obj$coefficients)[-1]
    coef[coef_nonzero] <- ls_coef
  }
  return(coef)
}

问题是到目前为止我们还没有失败的案例。

【讨论】:

  • NA 在这里做什么?不是if (any(is.na(new_x))) { ls_coef &lt;- coef}; else{ls.obj &lt;- lm(y ~ new_x);ls_coef &lt;- (ls.obj$coefficients)[-1];coef[coef_nonzero] &lt;- ls_coef}吗?
  • @AW27 tryCatch 抛出 NA 如果矩阵的子集因错误而失败。如果我们没有NA,则评估lm 代码,否则返回未更改的coef(抱歉在我编辑之前忘记了!)。
  • 到目前为止,这似乎暂时解决了我的问题,我将在更多的引导程序上尝试它,希望能够得到结果。感谢您的宝贵时间。
  • @AW27 不客气。当您确定一个重现失败的具体案例时,请通知我,以便我可以仔细查看。
  • 对不起,我打电话给purrr::map,因为我在数据框列表上运行我的方法。我使用的这个函数包含上述内容,这就是错误的来源,我将尝试lapply而不是purrr::map
猜你喜欢
  • 2014-10-01
  • 2015-08-20
  • 2014-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多