我正在使用lapply大量项目上的复杂函数,我想保存每个项目的输出(如果有的话)以及生成的任何警告/错误,以便我可以告诉哪个项目产生了哪个警告/错误.
我找到了一种方法来捕捉警告withCallingHandlers(在此描述).但是,我也需要捕获错误.我可以将它包装在一个tryCatch(如下面的代码中),但是有更好的方法吗?
catchToList <- function(expr) {
val <- NULL
myWarnings <- NULL
wHandler <- function(w) {
myWarnings <<- c(myWarnings, w$message)
invokeRestart("muffleWarning")
}
myError <- NULL
eHandler <- function(e) {
myError <<- e$message
NULL
}
val <- tryCatch(withCallingHandlers(expr, warning = wHandler), error = eHandler)
list(value = val, warnings = myWarnings, error=myError)
}
Run Code Online (Sandbox Code Playgroud)
此函数的示例输出是:
> catchToList({warning("warning 1");warning("warning 2");1})
$value
[1] 1
$warnings
[1] "warning 1" "warning 2"
$error
NULL
> catchToList({warning("my warning");stop("my error")})
$value …Run Code Online (Sandbox Code Playgroud) 我在下面有一个示例函数,它将日期作为字符串读入并将其作为日期对象返回.如果它读取的字符串无法转换为日期,则会返回错误.
testFunction <- function (date_in) {
return(as.Date(date_in))
}
testFunction("2010-04-06") # this works fine
testFunction("foo") # this returns an error
Run Code Online (Sandbox Code Playgroud)
现在,我想使用lapply并在日期列表中应用此函数:
dates1 = c("2010-04-06", "2010-04-07", "2010-04-08")
lapply(dates1, testFunction) # this works fine
Run Code Online (Sandbox Code Playgroud)
但是,如果我想在两个好日期中间的一个字符串返回错误时将该函数应用于列表,那么处理此问题的最佳方法是什么?
dates2 = c("2010-04-06", "foo", "2010-04-08")
lapply(dates2, testFunction)
Run Code Online (Sandbox Code Playgroud)
我认为我想在那里试一试,但是有没有办法捕获"foo"字符串的错误,同时要求lapply继续阅读第三个日期?
使用lapply和朋友编写的代码通常在眼睛上更容易,而且比循环更容易Rish.我和下一个人一样喜欢lapply,但是当出现问题时如何调试呢?例如:
> ## a list composed of numeric elements
> x <- as.list(-2:2)
> ## turn one of the elements into characters
> x[[2]] <- "what?!?"
>
> ## using sapply
> sapply(x, function(x) 1/x)
Error in 1/x : non-numeric argument to binary operator
Run Code Online (Sandbox Code Playgroud)
我使用了for循环:
> y <- rep(NA, length(x))
> for (i in 1:length(x)) {
+ y[i] <- 1/x[[i]]
+ }
Error in 1/x[[i]] : non-numeric argument to binary operator
Run Code Online (Sandbox Code Playgroud)
但我会知道错误发生在哪里:
> i
[1] 2
Run Code Online (Sandbox Code Playgroud)
使用lapply/sapply时我该怎么办?