78

When passing missing values to ggplot, it's very kind, and warns us that they are present. This is acceptable in an interactive session, but when writing reports, you do not the output get cluttered with warnings, especially if there's many of them. Below example has one label missing, which produces a warning.

library(ggplot2)
library(reshape2)
mydf <- data.frame(
  species = sample(c("A", "B"), 100, replace = TRUE), 
  lvl = factor(sample(1:3, 100, replace = TRUE))
)
labs <- melt(with(mydf, table(species, lvl)))
names(labs) <- c("species", "lvl", "value")
labs[3, "value"] <- NA
ggplot(mydf, aes(x = species)) + 
   stat_bin() + 
   geom_text(data = labs, aes(x = species, y = value, label = value, vjust = -0.5)) +
   facet_wrap(~ lvl)

enter image description here

If we wrap suppressWarnings around the last expression, we get a summary of how many warnings there were. For the sake of argument, let's say that this isn't acceptable (but is indeed very honest and correct). How to (completely) suppress warnings when printing a ggplot2 object?

M--
  • 25,431
  • 8
  • 61
  • 93
Roman Luštrik
  • 69,533
  • 24
  • 154
  • 197

3 Answers3

75

You need to suppressWarnings() around the print() call, not the creation of the ggplot() object:

R> suppressWarnings(print(
+ ggplot(mydf, aes(x = species)) + 
+    stat_bin() + 
+    geom_text(data = labs, aes(x = species, y = value, 
+                               label = value, vjust = -0.5)) +
+    facet_wrap(~ lvl)))
R> 

It might be easier to assign the final plot to an object and then print().

plt <- ggplot(mydf, aes(x = species)) + 
   stat_bin() + 
   geom_text(data = labs, aes(x = species, y = value,
                              label = value, vjust = -0.5)) +
   facet_wrap(~ lvl)


R> suppressWarnings(print(plt))
R> 

The reason for the behaviour is that the warnings are only generated when the plot is actually drawn, not when the object representing the plot is created. R will auto print during interactive usage, so whilst

R> suppressWarnings(plt)
Warning message:
Removed 1 rows containing missing values (geom_text).

doesn't work because, in effect, you are calling print(suppressWarnings(plt)), whereas

R> suppressWarnings(print(plt))
R>

does work because suppressWarnings() can capture the warnings arising from the print() call.

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
  • 1
    Interesting how explicitly calling `print` works but not when this is done implicitly by calling `ggplot` and not assigning it to an object. – Roman Luštrik Nov 08 '12 at 15:17
  • 1
    @RomanLuštrik That's because the actual call is something like `print(suppressWarnings(plt))` where you want `suppressWarnings(print(plt))` or did I miss what you meant? – Gavin Simpson Nov 08 '12 at 15:19
  • Yes, you've nailed it. I didn't think hard enough about how print is being called implicitly. – Roman Luštrik Nov 08 '12 at 15:25
  • How to remove any message from `ggplot` ? – Julien Apr 25 '23 at 09:42
  • I got message such as ``geom_line()`: Each group consists of only one observation. ℹ Do you need to adjust the group aesthetic?` – Julien Apr 25 '23 at 09:45
  • @Julien See `?tryCatch` for more detail, but also, this might relate to how the Posit folks are now doing better error messages and formatting them so actually handling this generically could be more involved. Note this Q&A is over a decade old and **ggplot2** has changed considerably in the meantime. You might do well to formulate your own question (linking to this Q&A to indicate why the approach here doesn't work now) and ask on [so] – Gavin Simpson Apr 25 '23 at 09:54
64

A more targeted plot-by-plot approach would be to add na.rm=TRUE to your plot calls. E.g.:

  ggplot(mydf, aes(x = species)) + 
      stat_bin() + 
      geom_text(data = labs, aes(x = species, y = value, 
                                 label = value, vjust = -0.5), na.rm=TRUE) +
      facet_wrap(~ lvl)
metasequoia
  • 7,014
  • 5
  • 41
  • 54
  • 2
    +1 Nice answer. It's always going to better to address the root cause of warnings and deal with these, rather than suppressing the warnings. – Andrie Nov 08 '12 at 14:20
  • +1 Agree with @Andrie, although I do find it reassuring to get the warning about missing values - it helps me have a check that it is doing the right thing. Not that I don't trust Hadley of course. – Gavin Simpson Nov 08 '12 at 14:44
  • 2
    FYI: For `stat_smooth` this technique doesn't work. (bug) – Don Scott Dec 02 '15 at 09:38
31

In your question, you mention report writing, so it might be better to set the global warning level:

options(warn=-1)

the default is:

options(warn=0)
csgillespie
  • 59,189
  • 14
  • 150
  • 185