How to suppress warnings globally in an R Script - r

I have a long R script that throws some warnings, which I can ignore.
I could use
suppressWarnings(expr)
for single statements. But how can I suppress warnings in R globally? Is there an option for this?

You could use
options(warn=-1)
But note that turning off warning messages globally might not be a good idea.
To turn warnings back on, use
options(warn=0)
(or whatever your default is for warn, see this answer)

You want options(warn=-1). However, note that warn=0 is not the safest warning level and it should not be assumed as the current one, particularly within scripts or functions. Thus the safest way to temporary turn off warnings is:
oldw <- getOption("warn")
options(warn = -1)
[your "silenced" code]
options(warn = oldw)

I have replaced the printf calls with calls to warning in the C-code now. It will be effective in the version 2.17.2 which should be available tomorrow night. Then you should be able to avoid the warnings with suppressWarnings() or any of the other above mentioned methods.
suppressWarnings({ your code })

Have a look at ?options and use warn:
options( warn = -1 )

As discussed in other answers, you probably want to set options(warn = -1) and revert to the old behavior. The withr packages allows you to set an option value and automatically revert to the old behavior.
# install.packages("withr")
withr::with_options(.new = list(warn = -1),
{code})
Alternatively, the local_* functions have the same effect until the end of the function they are included in.
function() {
withr::local_options(.new = list(warn = -1)
{ code }
}

Related

Why require() command is preferred within functions in R? [duplicate]

What is the difference between require() and library()?
There's not much of one in everyday work.
However, according to the documentation for both functions (accessed by putting a ? before the function name and hitting enter), require is used inside functions, as it outputs a warning and continues if the package is not found, whereas library will throw an error.
Another benefit of require() is that it returns a logical value by default. TRUE if the packages is loaded, FALSE if it isn't.
> test <- library("abc")
Error in library("abc") : there is no package called 'abc'
> test
Error: object 'test' not found
> test <- require("abc")
Loading required package: abc
Warning message:
In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
there is no package called 'abc'
> test
[1] FALSE
So you can use require() in constructions like the one below. Which mainly handy if you want to distribute your code to our R installation were packages might not be installed.
if(require("lme4")){
print("lme4 is loaded correctly")
} else {
print("trying to install lme4")
install.packages("lme4")
if(require(lme4)){
print("lme4 installed and loaded")
} else {
stop("could not install lme4")
}
}
In addition to the good advice already given, I would add this:
It is probably best to avoid using require() unless you actually will be using the value it returns e.g in some error checking loop such as given by thierry.
In most other cases it is better to use library(), because this will give an error message at package loading time if the package is not available. require() will just fail without an error if the package is not there. This is the best time to find out if the package needs to be installed (or perhaps doesn't even exist because it it spelled wrong). Getting error feedback early and at the relevant time will avoid possible headaches with tracking down why later code fails when it attempts to use library routines
You can use require() if you want to install packages if and only if necessary, such as:
if (!require(package, character.only=T, quietly=T)) {
install.packages(package)
library(package, character.only=T)
}
For multiple packages you can use
for (package in c('<package1>', '<package2>')) {
if (!require(package, character.only=T, quietly=T)) {
install.packages(package)
library(package, character.only=T)
}
}
Pro tips:
When used inside the script, you can avoid a dialog screen by specifying the repos parameter of install.packages(), such as
install.packages(package, repos="http://cran.us.r-project.org")
You can wrap require() and library() in suppressPackageStartupMessages() to, well, suppress package startup messages, and also use the parameters require(..., quietly=T, warn.conflicts=F) if needed to keep the installs quiet.
Always use library. Never use require.
tl;dr: require breaks one of the fundamental rules of robust software systems: fail early.
In a nutshell, this is because, when using require, your code might yield different, erroneous results, without signalling an error. This is rare but not hypothetical! Consider this code, which yields different results depending on whether {dplyr} can be loaded:
require(dplyr)
x = data.frame(y = seq(100))
y = 1
filter(x, y == 1)
This can lead to subtly wrong results. Using library instead of require throws an error here, signalling clearly that something is wrong. This is good.
It also makes debugging all other failures more difficult: If you require a package at the start of your script and use its exports in line 500, you’ll get an error message “object ‘foo’ not found” in line 500, rather than an error “there is no package called ‘bla’”.
The only acceptable use case of require is when its return value is immediately checked, as some of the other answers show. This is a fairly common pattern but even in these cases it is better (and recommended, see below) to instead separate the existence check and the loading of the package. That is: use requireNamespace instead of require in these cases.
More technically, require actually calls library internally (if the package wasn’t already attached — require thus performs a redundant check, because library also checks whether the package was already loaded). Here’s a simplified implementation of require to illustrate what it does:
require = function (package) {
already_attached = paste('package:', package) %in% search()
if (already_attached) return(TRUE)
maybe_error = try(library(package, character.only = TRUE))
success = ! inherits(maybe_error, 'try-error')
if (! success) cat("Failed")
success
}
Experienced R developers agree:
Yihui Xie, author of {knitr}, {bookdown} and many other packages says:
Ladies and gentlemen, I've said this before: require() is the wrong way to load an R package; use library() instead
Hadley Wickham, author of more popular R packages than anybody else, says
Use library(x) in data analysis scripts. […]
You never need to use require() (requireNamespace() is almost always better)
?library
and you will see:
library(package) and require(package) both load the package with name
package and put it on the search list. require is designed for use
inside other functions; it returns FALSE and gives a warning (rather
than an error as library() does by default) if the package does not
exist. Both functions check and update the list of currently loaded
packages and do not reload a package which is already loaded. (If you
want to reload such a package, call detach(unload = TRUE) or
unloadNamespace first.) If you want to load a package without putting
it on the search list, use requireNamespace.
My initial theory about the difference was that library loads the packages whether it is already loaded or not, i.e. it might reload an already loaded package, while require just checks that it is loaded, or loads it if it isn't (thus the use in functions that rely on a certain package). The documentation refutes this, however, and explicitly states that neither function will reload an already loaded package.
Here seems to be the difference on an already loaded package.
While it is true that both require and library do not load the package. Library does a lot of other things before it checks and exits.
I would recommend removing "require" from the beginning of a function running 2mil times anyway, but if, for some reason I needed to keep it. require is technically a faster check.
microbenchmark(req = require(microbenchmark), lib = library(microbenchmark),times = 100000)
Unit: microseconds
expr min lq mean median uq max neval
req 3.676 5.181 6.596968 5.655 6.177 9456.006 1e+05
lib 17.192 19.887 27.302907 20.852 22.490 255665.881 1e+05

testthat fails within devtools::check but works in devtools::test

Is there any way to reproduce the environment which is used by devtools::check?
I have the problem that my tests work with devtools::test() but fail within devtools::check(). My problem is now, how to find the problem. The report of check just prints the last few lines of the error log and I can't find the complete report for the testing.
checking tests ... ERROR
Running the tests in ‘tests/testthat.R’ failed.
Last 13 lines of output:
...
I know that check uses a different environment compared to test but I don't know how I should debug these problems since they are not reproducible at all. Specially these test where running a few month ago, so not sure where to look for the problem.
EDIT
actually I tried to locate my problem and I found a solution. But to post my solution to it, I have to add more details.
So my test always failed since I was testing a markdown script if it is running without errors and afterwards I was checking if some of the environmental variables are set correctly. These where results which I calculate with the script as well as standard settings which I set. So I wanted to get a warning if I forgot to change some of my settings after developing...
Anyway, since it is a markdown script, I had to extract the code and I was using comments from this post knitr: run all chunks in an Rmarkdown document using knitr::purl to get the code and sys.source to execute it.
runAllChunks <- function(rmd, envir=globalenv()){
# as found here https://stackoverflow.com/questions/24753969
tempR <- tempfile(tmpdir = '.', fileext = ".R")
on.exit(unlink(tempR))
knitr::purl(rmd, output=tempR, quiet=TRUE)
sys.source(tempR, envir=envir)
}
For some reason, this produces an error since maybe a few weeks (not sure which new packages I installed lately...). But since there is a new comment, that I can just use knitr::knit which also executes the code, this worked as expected and now my test no longer complains.
So in the end, I don't know where the problem exactly was, but this is now working.
I recently had a similar issue with my tests breaking (succeeding with devtools::test() but failing with devtools::check()). I don't know if this solution necessarily fixes the problem above, but it should help to track down similar problems.
In my case, the problem ultimately came down to using a function that needed a package listed in Suggests rather than in Imports/Depends. In particular, my function called httr::content(), which broke when I tried to pass it the as = "parsed" argument. It turns out that as = "parsed" uses a suggested package, readr to read a csv, and I needed to add it to my dependencies for devtools::check() to work.
This is a known issue with testthat. The workaround is to add the following as the 1st line in tests/testthat.R:
Sys.setenv(R_TESTS="")
In case it helps someone else, this is what worked for me
Re-install all relevant packages. E.g. install.packages("testthat", "dplyr", "lubridate", "stringr") (I included all packages my package uses)
Close RStudio and reopen
Then all tests passed
I spent much too long looking into this error, so hoping that I can help someone out in the future. I would like to add to this that I was getting this error while using ggplot2::autoplot() in my function and it required that I added #import ggfortify to the Roxygen skeleton part of my function.
I ran into the same issue with my tests failing under devtools::check() while not failing under testthat::test()
And none of the above applied to my problem, so i decided to post my issue plus solution here as well. But first some NOTEs from my experience:
devtools::check() does - so it seems - deeper error checking then your own written tests.
Now to my code-setup. I had a function that was build to retrieve values from two different files. Those files contained named profiles with a set of values per profile. But the profiles were named differently, depending on the files:
Example files:
Content of file_one:
[default]
value_A = "foo"
value_B = "bar"
value_C = "baz"
[peter]
value_A = "oof"
value_B = "rab"
value_C = "zab"
content of file_two:
[default]
value_X = "fuzzly"
value_Z = "puzzly"
[profile peter]
value_X = "fuzzly"
value_Z = "puzzly"
As you can see, does the naming in file two follow another naming convention, when it comes to the named profiles. The profiles are written in "[]" and the default-profile is always '[default]' in both files. But as soon as it comes to named profiles, its just '[name]' in one file and then '[profile name]' in the other one.
Now i've build the function like that (simplyfied):
get_value <- function(file_content, what, profile) {
file_content <- readr::read_lines(file)
all_profiles_at <- grep("\\[.*\\]", file_content)
profile_regex <- paste0("\\[",if(file_content == "file_two" && profile != "default") "profile ",profile,"\\]")
profile_at <- grep(profile_regex, file_content)
profile_ends_at <- if(profile_at == max(all_profiles_at)) length(file_content) else all_profiles_at[grep(paste0("^",profile_at,"$"), all_profiles_at) + 1] -1
profile_content <- file_content[profile_at:profile_ends_at]
whole_what <- stringr::str_replace_all(profile_content[grep(paste0("^",what,".*"), profile_content)], " ", "")
return(stringr::str_sub(whole_what, stringr::str_length(paste0(what,"=."))))
}
With this code my tests ran smoothly and even check() found no issues.
While the whole code evolved i figured, that i should read the files content beforehand and give only the alread read_in content to the function to avoid duplication in my code. So i changed the function like so:
get_value <- function(file, what, profile) {
is_file_two <- is_file_two(file_content)
all_profiles_at <- grep("\\[.*\\]", file_content)
profile_regex <- paste0("\\[",if(file_content == "file_two" && profile != "default") "profile ",profile,"\\]")
profile_at <- grep(profile_regex, file_content)
profile_ends_at <- if(profile_at == max(all_profiles_at)) length(file_content) else all_profiles_at[grep(paste0("^",profile_at,"$"), all_profiles_at) + 1] -1
profile_content <- file_content[profile_at:profile_ends_at]
whole_what <- stringr::str_replace_all(profile_content[grep(paste0("^",what,".*"), profile_content)], " ", "")
return(stringr::str_sub(whole_what, stringr::str_length(paste0(what,"=."))))
}
As you might notice i only changed the first line of the funciton body and left the if-condition unchanged - my mistake!
But my tests didn't throw an error, as the if-condition still worked. Even though the 'file_content == "file_two"' part now generated a logical vector and if() ... else ... normally throws a warning, when the logical has length > 1. The special construct with the && doesn't throw such an error as it returns a length(1) logical:
# with warning
if(c(FALSE, FALSE, FALSE)) "Done!" else "Not done!"
# no warning:
if(c(FALSE, FALSE, FALSE) && TRUE) "Done!" else "Not done!"
Thats why my tests with testthat::test() sill worked.
But devtools::check() saw this flaw in my code and the tests failed!
And that part of the FAILURE_REPORT showed me my errors:
[...]
where 41: test_check("my_package_name")
--- value of length: 18 type: logical ---
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE
--- function from context ---
[...]
Conclusion:
testthat::test() is great! Is checks whether or not your code still runs. But devtools::check() goes far deeper - and when your tests pass with testthat::test() but fail with devtools::check() then you've probaly got some deeper bugs and flaws in your code you MUST attend to!
So as I shortly mentioned above, I changed some of my code to no longer user knitr::purl but using knitr::knit and this solved my problem.
expect_error(f <- runAllChunks('010_main_lfq_analysis.Rmd'), NA)
expect_error(f <- knitr::knit('010_main_lfq_analysis.Rmd', output='jnk.R', quiet=TRUE, envir=globalenv()), NA)
This could also happen in the following scenario: You have a library already loaded in R and you are referring to the function in that library without namespace binding. For example, suppose you use the nnzero() function from the Matrix in a test file and happen to also have had the Matrix package already loaded with library(Matrix). Then devtools::test() will pass but devtools::check() fails. Using Matrix::nnzero() should fix the problem.

How to avoid printing / showing messages

this question has been asked before but non of the answers is working for me.
I am using the library rhdf5 from bioconductor.org to read HDF5 files: source("http://bioconductor.org/biocLite.R"); biocLite("rhdf5"); library(rhdf5);
When I use the h5read function to read particular variables that contain references the following warning message is printed:
"Warning: h5read for type 'REFERENCE' not yet implemented. Values replaced by NA's"
(It is not shown in red like errors and warnings in RStudio. Just in black)
The warning is OK for me as I don't need those references. But I use this function to read hundreds of variables, so my screen gets polluted with these messages.
For example:
a <-h5read(f, "/#Link2#")
Warning: h5read for type 'REFERENCE' not yet implemented. Values replaced by NA's
Warning: h5read for type 'REFERENCE' not yet implemented. Values replaced by NA's
I have tried all suggestions I found (capture.output, suppressMessage/Warning, sink, options(warn, max.print, show.error.messages):
capture.output(a <- h5read(f, "/#Link2#"), file='/dev/null')
I also tried invisible just in case: invisible(capture.output(a <- h5read(f, "/#Link2#"), file='/dev/null'))
suppressWarnings(suppressMessages(a <- h5read(f, "/#Link2#")))
I also tried suppressForeignCheck and suppressPackageStartupMessages just in case
{sink("/dev/null"); a <-h5read(f, "/#Link2#"); sink()}
{options(warn=-1, max.print=1,show.error.messages=FALSE); a <-h5read(f, "/#Link2#") }
They all keep producing the same warning messages.
Does anyone knows any other thing I might try, or why are these things not working?
How does the library manages to print the messages skipping all these? Sounds that I might be doing something wrong...
Any help is appreciated.
Just as reference these are the other posts I used:
r: do not show warnings
How to suppress warnings globally in an R Script
suppress messages displayed by "print" instead of "message" or "warning" in R
Suppress one command's output in R
You should ask maintainer("rhdf5") to provide a solution -- print message less frequently, and use standard R warnings -- the message is from C code and uses printf() rather than Rf_warning() or Rf_ShowMessage() or Rprintf() / REprintf().
Here's an illustration of the problem
> library(inline)
> fun = cfunction(character(), 'printf("hello world\\n"); return R_NilValue;')
> fun()
hello world
NULL
> sink("/dev/null"); fun(); sink()
hello world
>
and a solution -- use Rf_warning() to generate R warnings. The example also illustrates how writing to R's output stream via Rprintf() would then allow the output to be captured with sink.
> fun = cfunction(character(), 'Rf_warning("hello world"); return R_NilValue;')
> x = fun()
Warning message:
In fun() : hello world
> x = suppressWarnings(fun())
> fun = cfunction(character(), 'Rprintf("hello world\\n"); return R_NilValue;')
> sink("/dev/null"); fun(); sink()
>
None of this helps you directly, though!
UPDATE the maintainer updated the code in the 'devel' branch of the package, version 2.17.2.

R: Sometimes system.file not working as documented

The system.file commands in my package examples sometimes fail unpredictably, while passing at other times. I do not understand why.
I typically use:
> system.file("examples", "trees.xml", package="RNeXML", mustWork=TRUE)
which usually works, but sometimes fails (even in an interactive session):
Error in system.file("examples", "trees.xml", package = "RNeXML", mustWork = TRUE) :
no file found
when it is failing, I can get this to work:
> system.file("examples", "trees.xml", lib.loc = .libPaths()[1], package="RNeXML", mustWork=TRUE)
[1] "/home/cboettig/R/x86_64-pc-linux-gnu-library/3.0/RNeXML/examples/trees.xml"
Which doesn't make any sense to me, because the documentation of system.file says that it checks libPaths automatically if no value for lib.loc is provided.
So why does it work if I give the .libPaths()[1] explicitly?
It seems like explicitly telling my package to use the first path, .libPaths()[1], would be less stable.
Since this is a heisenbug, set options(error = recover) and when prompted for a frame number, pick the one that brings you into system.file. (For more on what I'm about to explain, see Hadley's Exceptions and Debugging tutorial.) Then step through using the debugger and determine if packagePath gets loaded correctly using find.package(package, lib.loc, quiet = TRUE). I inspected this latter function and couldn't find anything immediately wrong, so it may be something system-specific. Could you post your sessionInfo()?
If packagePath is fine, then the answer lies somewhere in the rest of system.file's body:
FILES <- file.path(packagePath, ...)
present <- file.exists(FILES)
if (any(present))
FILES[present]
else ""
This would make life very hard for us since I doubt there are problems with any of these functions. If packagePath is not what you expect, you can use the recover frame number prompt again to dive back into system.file, and this time type debug(find.package) so you can step through that function. Inspect dirs and paths after the for (lib in lib.loc), and step through the few ifs that follow.
If none of these work, and you don't spot any mischief (which is very hard with the transparency of a step-by-step debugger), you can always try to dump.frames and upload the file for us. I am not sure how useful it will be, since even if we install the same packages, there may be path issues, but it's worth a shot.
Finally, if you don't care about all of the above, a hack that works would be:
trees_path <- ""
for(lib in .libPaths()) {
trees_path <- system.file("examples", "trees.xml", lib.loc = lib, package="RNeXML", mustWork = FALSE)
if (trees_path != "") break;
}
if (trees_path == "") stop("examples/trees.xml not found using any library paths")

Require minimum version of R package

I just noticed that there's no version argument to R's require() or library() functions. What do people do when they need to ensure they have at least some minimum version of a package, so that e.g. they know some bug is fixed, or some feature is available, or whatever?
I'm aware of the Depends stuff for package authors, but I'm looking for something to use in scripts, interactive environments, org-mode files, code snippets, etc.
You could use packageVersion():
packageVersion("stats")
# [1] ‘2.14.1’
if(packageVersion("stats") < "2.15.0") {
stop("Need to wait until package:stats 2.15 is released!")
}
# Error: Need to wait until package:stats 2.15 is released!
This works because packageVersion() returns an object of class package_version for which < behaves as we'd like it to (which < will not do when comparing two character strings using their lexicographical ordering).
After reading Paul's pseudocode, here's the function I've written.
use <- function(package, version=0, ...) {
package <- as.character(substitute(package))
library(package, ..., character.only=TRUE)
pver <- packageVersion(package)
if (compareVersion(as.character(pver), as.character(version)) < 0)
stop("Version ", version, " of '", package,
"' required, but only ", pver, " is available")
invisible(pver)
}
It functions basically the same as library(), but takes an extra version argument:
> use(plyr, 1.6)
> use(ggplot2, '0.9')
Error in use(ggplot2, "0.9") :
Version 0.9 of 'ggplot2' required, but only 0.8.9 is available
I am not aware of such a function, but it should be quite easy to make one. You can base it on sessionInfo() or packageVersion(). After loading the packages required for the script, you can harvest the package numbers from there. A function that checks the version number would look like (in pseudo code, as I don't have time right now):
check_version = function(pkg_name, min_version) {
cur_version = packageVersion(pkg_name)
if(cur_version < min_version) stop(sprintf("Package %s needs a newer version,
found %s, need at least %s", pkg_name, cur_version, min_version))
}
Calling it would be like:
library(ggplot2)
check_version("ggplot2", "0.8-9")
You still need to parse the version numbers into something that allows the comparison cur_version < min_version, but the basic structure remains the same.

Resources