On 12-10-21 09:08 PM, Martin Morgan wrote: > On 10/21/2012 12:28 PM, Ben Bolker wrote: >> >> Not desperately important, but nice to have and possibly of use to >> others, is the ability to suppress specific warnings rather than >> suppressing warnings indiscriminately. I often know of a specific >> warning that I want to ignore (because I know that's it's a false >> positive/ignorable), but the current design of suppressWarnings() forces >> me to ignore *any* warnings coming from the expression. >> >> I started to write a new version that would check and, if supplied >> with a regular expression, would only block matching warnings and >> otherwise would produce the warnings as usual, but I don't quite know >> enough about what I'm doing: see ??? in expression below. >> >> Can anyone help, or suggest pointers to relevant >> examples/documentation (I've looked at demo(error.catching), which isn't >> helping me ... ?) >> >> suppressWarnings2 <- function(expr,regex=NULL) { >> opts <- options(warn = -1) >> on.exit(options(opts)) > > I'm not really sure what the options(warn=-1) is doing there, maybe its > for efficiency to avoid generating a warning message (as distinct from > signalling a warning).
As may have been obvious, I was copying suppressWarnings() verbatim -- so I guess you'd have to ask R-core for the reasoning there ... > I think you're after something like > > suppressWarnings2 <- > function(expr, regex=character()) > { > withCallingHandlers(expr, warning=function(w) { > if (length(regex) == 1 && length(grep(regex, > conditionMessage(w)))) { > invokeRestart("muffleWarning") > } > }) > } > > If the restart isn't invoked, then the next handler is called and the > warning is handled as normal. So with > > f <- function() { > warning("oops") > 2 > } > > there is > >> suppressWarnings2(f()) > [1] 2 > Warning message: > In f() : oops >> suppressWarnings2(f(), "oops") > [1] 2 Great, thank you! > > For your own code I think a better strategy is to create a sub-class of > warnings that can be handled differently > > mywarn <- > function(..., call.=TRUE, immediate.=FALSE, domain=NULL) > { > msg <- .makeMessage(..., domain=domain, appendLF=FALSE) > call <- NULL > if (call.) > call <- sys.call(1L) > class <- c("silencable", "simpleWarning", "warning", "condition") > cond <- structure(list(message=msg, call=call), class=class) > warning(cond) > } > > suppressWarnings3 <- > function(expr) > { > withCallingHandlers(expr, silencable=function(w) { > invokeRestart("muffleWarning") > }) > } > > then with > > g <- function() { > mywarn("oops") > 3 > } > >> suppressWarnings3(f()) > [1] 2 > Warning message: > In f() : oops >> g() > [1] 3 > Warning message: > In g() : oops >> suppressWarnings3(g()) > [1] 3 > >> withCallingHandlers(expr, warning = function(w) { >> ## browser() >> if (is.null(regex) || grepl(w[["message"]],regex)) { >> invokeRestart("muffleWarning") >> } else { >> ## ? what do I here to get the warning issued? >> ## browser() >> ## computeRestarts() shows "browser", >> ## "muffleWarning", and "abort" ... >> options(opts) >> warning(w$message) >> ## how can I get back from here to the calling point >> ## *without* muffling warnings ... ? >> } >> }) >> } >> >> suppressWarnings2(sqrt(-1)) >> suppressWarnings2(sqrt(-1),"abc") >> >> It seems to me I'd like to have a restart option that just returns to >> the point where the warning was caught, *without* muffling warnings ... >> ? But I don't quite understand how to set one up ... >> >> Ben Bolker >> >> ______________________________________________ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel