我正在使用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) 包中的geom_density_ridgesgeom ggridges创建了脊线,如果没有指定带宽,它会尝试找到合理的值.然后使用baseR message函数报告该值(请参阅https://twitter.com/ClausWilke/status/921363157553172480).
的base一个R函数suppressMessages功能被设计为抑制这样的消息.例如,此代码输出一条消息:
message('This is a message');
Run Code Online (Sandbox Code Playgroud)
这段代码什么都没输出:
suppressMessages(message('This is a message'));
Run Code Online (Sandbox Code Playgroud)
但是,出于某种原因,当将这个geom添加到ggplot时,抑制消息似乎被抑制了.下面的代码也仍然会产生一条消息:
require('ggplot2');
require('ggridges');
suppressMessages(ggplot(Orange, aes(x=age,y=Tree)) + geom_density_ridges());
Run Code Online (Sandbox Code Playgroud)
(具体来说," Picking joint bandwidth of 319".)
为什么是这样?ggplot无论用户的规格如何,是否确实能够确保消息传递?或者这实际上是我刚才不知道的明智行为?
生成RMarkdown报告时,message可以将chunk选项设置为message=FALSE,这将抑制呈现级别的所有消息.因为那是我的用例,我的问题就解决了.
正如该ggridges软件包的作者Claus Wilke 建议的那样,您可以随时bandwidth手动设置以避免消息(https://twitter.com/ClausWilke/status/921361195231215616).
但为什么不suppressMessages首先压制消息呢?
我恰好不知道这种预期的行为吗?