【问题标题】:using trycatch which returns the context of the error使用 trycatch 返回错误的上下文
【发布时间】:2017-05-18 14:22:12
【问题描述】:

这里我有这个函数:(删除对象是我们不想计算的函数的名称)

    func <- function(x, remove=NULL) {
  if(class(x)%in%"igraph"){
  doclist <- list("edgelist"=function(x) as.edgelist(x),
                    "adjacencyMatrix"=function(x)as_adjacency_matrix(x),
                    "incidenceMatrix"=function(x) as_incidence_matrix(x, 0.001),
                    "data.frame"=function(x) as_data_frame(x))

  sapply(doclist[setdiff(names(doclist), remove)], function(f) f(n))}
  else stop("The input is not an igraph object")
}

如何在这个函数中使用 tryCatch?如果 'doclist' 中的任何函数遇到错误,'doclist' 的下一行将执行。最终结果消息警告调用有错误的函数的名称和错误的上下文。

【问题讨论】:

  • 您的问题无法理解。你能把它们写得更清楚吗,例如用几个简短的句子/问题,还是使用更多的标点符号?
  • @user1310503 抱歉造成误会。我试图尽可能地改进。希望我能正确表达我的意思。
  • 如果doclist 中的任何函数失败,您希望它继续运行,最后您希望它给出包含这些函数名称和错误消息的警告。对吗?
  • @user1310503 确切地说,当然是作为数据框的计算值。

标签: r function try-catch


【解决方案1】:

这里有一些代码,基本上展示了如何做到这一点。它不使用igraph 对象或doclist 中的函数,因此您必须自己调整它以使用它们。

首先,这里有两个会引发错误的函数:

g <- function(y) { 
    stop("g failed")
}
h <- function(y) { 
    stop("h failed")
}

这里是你的函数的清理版本,在doclist 中使用了一些不同的函数:

func <- function(x, remove=NULL) {
    if (!is(x, "numeric")) 
        stop("x must be a numeric")

    doclist <- list(
        sum = function(x) sum(x),
        g = function(x) g(x),
        makeMatrix = function(x) matrix(x, nrow=3, ncol=3),
        h = function(x) h(x)
    )
    doclist <- doclist[setdiff(names(doclist), remove)]

    warningsText <- ""
    result <- lapply(names(doclist), 
        function(functionName, x) {
            f <- doclist[[functionName]]
            tryCatch(f(x), 
                error = function(e) {
                    warningsText <<- paste0(warningsText, 
                        "\nError in ", functionName, ":\n", e$message)
                    return(NULL)
                }) 
        }, x)

    if (nchar(warningsText) > 0) 
        warning(warningsText)
    return(result)
}

这就是它产生的结果:

> func(1:2)
[[1]]
[1] 3

[[2]]
NULL

[[3]]
     [,1] [,2] [,3]
[1,]    1    2    1
[2,]    2    1    2
[3,]    1    2    1

[[4]]
NULL

Warning messages:
1: In matrix(x, nrow = 3, ncol = 3) :
  data length [2] is not a sub-multiple or multiple of the number of rows [3]
2: In func(1:2) : 
Error in g:
g failed
Error in h:
h failed

注意事项:

  • 对于引发错误的函数,这会将 NULL 放入结果列表中。
  • 所有错误都归为一个警告。在带有func(1:2) 的示例中,这是显示的第二个警告。
  • for 循环会比 lapplysapply 更好,但我还没有这样做。
  • lapply 优于 sapply,因为函数都返回不同类型的对象。
  • 最好将x 包含在lapply 内的无名函数的参数中,并将其作为lapply 的第三个参数。
  • lapply 的第一个参数应该是函数名,以便函数名和函数本身都可用于lapply 中的无名函数。

【讨论】:

  • 非常感谢您的出色回答。感谢您的时间。 @user1310503
  • 感谢您对此函数的帮助,但我有一个额外的问题,如果您回答我会很高兴:您知道如何将函数名称粘贴到结果中而不是 [ [1]] 例如?
  • 要使result 列表使用函数的名称,您可以在return 之前执行names(result) &lt;- names(doclist)
  • @user1210503 感谢您的关注和回复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-26
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多