Nicholas Normandin Nicholas Normandin - 3 months ago 11
R Question

Delayed warning messages using suppressWarnings in R script when resetting par()

Problem: I'm trying to write a script for an R package and in order to be conscientious to my users I'm saving their graphical parameters before plotting anything so that I can reset them at the end of the script. I understand that it's normal to receive warning messages when doing this because some of them can't be reset, but I'm using

suppressWarnings()
to try to avoid that output reaching the user. Here's a reduced example:

Plot4Things <- function(){

# suppress warnings when saving parameters
suppressWarnings(opar <- par())

# adjust parameter
par(mfrow = c(2,2))

plot(seq(1,20), pch = 16)
plot(seq(1,20), pch = 17)
plot(seq(1,20), pch = 18)
plot(seq(1,20), pch = 19)

# suppress warnings while restoring original parameters
suppressWarnings(par(opar))
}


Calling this function the first time gives me no warning messages or console output. Just a nice graph, and I verify that the
mfrow
option is reset properly using
par()
. However, each subsequent time I call the
Plot4Things()
function I get the following output:

Plot4Things()
Plot4Things()
# There were 12 warnings (use warnings() to see them)


The warnings are innocuous things about graphical parameters that can't be reset (which is fine because I'm not trying to). I'm not at all tied to this method of saving/resetting parameters, so is there a better way to do this? Is there a way to get the warning messages to stop making a delayed appearance? Deep down I really just want to understand the behavior so that I can improve my writing in the future.

Thanks in advance!

Answer

To set your parameters and save the old ones for restoring, use no.readonly:

opar <- par(no.readonly = TRUE)

Then you can avoid using suppressWarnings altogether.

And, as mentioned in the comment, put the cleanup into an on.exit that you declare directly after saving the par at the beginning of your function:

opar <- par(no.readonly = TRUE)
on.exit(par(opar))

As a caveat, the documentation’s example warns, with respect to using no.readonly, that

… this is not in general good practice

… but it doesn’t go on to explain why. I would therefore simply ignore this caveat.