32

Many R packages I work with involve functions that give all their messages and warnings through commands to print() calls rather than commands to message() or warning(). I'd like to be able to silence these functions progress indicators, etc, but the standard supressWarnings() or supressMessages doesn't do it. Is there a way I can just suppressPrint?

For example:

silly_developer_function <- function(x){
   print("Thanks for using my function!!")
   if(is(x, "numeric"))
     print("warning, x should be a character")
   x
}

I'd like to have a simple function suppressPrint() that I could wrap around a call to this function that would suppress the warning and useless messages (but still print the return value).

cboettig
  • 12,377
  • 13
  • 70
  • 113
  • There is the hackish strategy of using `sink`, but there may be a better way. – joran Jan 10 '12 at 01:11
  • @cboettig -- Your proposed edit of Simon's solution is nice, but would be better included as an edit/addendum to your own post. Thanks. – Josh O'Brien Jan 10 '12 at 01:58
  • @JoshO'Brien Thanks for the pointer. Do I edit my original question with that proposal then? Seems strange to turn the question into an answer? – cboettig Jan 10 '12 at 02:11
  • @cboettig -- Yep, that's exactly how I'd do it (and have often seen it done on SO). You can reference Simon Urbanek as the source of the idea, and say (in essence) 'so here's what I did with that idea'. – Josh O'Brien Jan 10 '12 at 02:15

2 Answers2

46

Well, those packages are buggy to start with. Use of print() for anything but side-effect in print implementations is a serious mistake.

That said, you can simply use capture.output() to collect the output from such code instead of printing it. So for the above it would be

capture.output(x <- silly_developer_function(...))
print(x)
Simon Urbanek
  • 13,842
  • 45
  • 45
  • Great solution. I might assign the output of capture.output to avoid it printing. Agreed that this is a work around buggy code, but the use of print instead of message() is rampant in packages I use so your solution is quite handy! – cboettig Jan 10 '12 at 02:13
  • 3
    FWIW if you're worried about the output on the console (which adds `print(..)` automatically) you can wrap the `capture.output` in `invisible(...)` – Simon Urbanek Jan 10 '12 at 02:35
  • Thanks, that's useful. I encounter this problem in writing Sweave vignettes that loop over some such functions, and Sweave/knitr also adds print automatically. Ideally this could be repressed in the Sweave options the way messages and warnings can. – cboettig Jan 10 '12 at 17:46
  • @SimonUrbanek Thanks for this answer, it helped me. I know this is an old question, but what difference would it make to add `invisible(...)` around `capture.output`? I have tried this in a loop, but there is no obvious difference with and without `invisible`. The `?` files don't make it clear what it does in this context. Thanks – EcologyTom Mar 23 '18 at 09:54
0

Another hacky way is to override the default print function. It will affect some functionality, such as printing the body of functions, but objects with their own print methods still get returned as usual.

print <- function(...) {}

> silly_developer_function("a")
[1] "a"
> silly_developer_function(1)
[1] 1
James
  • 65,548
  • 14
  • 155
  • 193