Re: [Rd] suppress *specific* warnings?

From: Martin Maechler <maechler_at_stat.math.ethz.ch>
Date: Thu, 25 Oct 2012 11:28:23 +0200

Sorry guys, for coming late,
but *please* don't go there.

I've been there years ago,
and found later why the approach is flawed "by design" :

Internationalization / Localization:

The really dangerous thing about matching error / warning messages -- I had done it in the past with the error message I caught via tryCatch() --
is that
- in your tests the code will work perfectly. - on CRAN the code will work perfectly, as "they" also use   the English (or C) locale.

So, by doing this you are distributing code that "almost always" works ... in your environment if you are US, UK or similarly based.

Indeed, a *really* dangerous practice.

Martin Maechler, ETH Zurich

>>>>> Martin Morgan <mtmorgan_at_fhcrc.org> >>>>> on Tue, 23 Oct 2012 05:28:48 -0700 writes:

    > On 10/22/2012 09:57 AM, luke-tierney_at_uiowa.edu wrote:
    >> On Sun, 21 Oct 2012, 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
    >> 
    >> The sources in srs/library/base/conditions.R have
    >> 
    >> suppressWarnings <- function(expr) {
    >> ops <- options(warn = -1) ## FIXME: temporary hack until R_tryEval
    >> on.exit(options(ops))     ## calls are removed from methods code
    >> withCallingHandlers(expr,
    >> warning=function(w)
    >> invokeRestart("muffleWarning"))
    >> }
    >> 
    >> I uspect we have still not entirely eliminated R_tryEval in this context
    >> but I'm not sure. Will check when I get a chance.
    >> 

>>> a warning). 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")
>>> }
>>> })
>>> }
    >> 
    >> A problem with using expression matching is of course that this fails
    >> with internationalized messages. Ideally warnings should be signaled as
    >> warning conditions of a particular class, and that class can be used
    >> to discriminate. Unfortunately very few warnings are designed this way.

    > Probably specific messages, rather than patterns, would be handled and then

    > suppressWarnings2 <- function(expr, messages = character())
    > {
    > opts <- options(warn = -1)
    > on.exit(options(ops))
    > withCallingHandlers(expr, warning=function(w) {
    > if (conditionMessage(w) %in% messages)
    > invokeRestart("muffleWarning")
    > })
    > }

    > gives one the illusion of speaking many languages

    > suppressWarnings2(log(-1), gettext("NaNs introduced", domain="R"))

    > Martin

    >> 
    >> Best,
    >> 
    >> luke
    >> 

>>>
>>> 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
>>>
>>> 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_at_r-project.org mailing list
    >>>> https://stat.ethz.ch/mailman/listinfo/r-devel
    >>>> 

>>>
>>>
>>>

    >>
    > -- 
    > Computational Biology / Fred Hutchinson Cancer Research Center
    > 1100 Fairview Ave. N.
    > PO Box 19024 Seattle, WA 98109

    > Location: Arnold Building M1 B861
    > Phone: (206) 667-2793

    > ______________________________________________
    > R-devel_at_r-project.org mailing list     > https://stat.ethz.ch/mailman/listinfo/r-devel

R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Thu 25 Oct 2012 - 09:32:13 GMT

This quarter's messages: by month, or sorted: [ by date ] [ by thread ] [ by subject ] [ by author ]

All messages

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Thu 25 Oct 2012 - 15:50:52 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.

list of date sections of archive