[Rd] suppress *specific* warnings?

Duncan Murdoch murdoch.duncan at gmail.com
Thu Oct 25 12:51:25 CEST 2012


On 12-10-25 5:28 AM, Martin Maechler wrote:
> 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:
>
> - If the warning comes from a "standard R" function,
>    the warning is almost surely different in a (say) German
>    locale, and your pattern won't be detected.
>
> - Ditto if from a recommended package.
>
> - If it is a warning that is not translated then it may be that
>    it is just not *YET*  translated.

I think the other Martin's suggestion addressed this:  he matched the 
translated message, not the English original.

Duncan Murdoch

>
> 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
>



More information about the R-devel mailing list