'R function `require` does not work as expected in `sapply`
I want to check if a bunch of packages are correctly installed (to make a dockerfile crash and not silently continue).
I tried a sapply on a list of package names, and this is what happens. Note that:
- 'not_available' is not installed :)
- 'testthat' is installed.
# to show the invisible output:
> show <- function(x) {cat(x, '\n')}
> show(require('not_available'))
Loading required package: not_available
FALSE
Warning message:
In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
there is no package called ‘not_available’
So far so good, precisely as expected.
> show(require('testthat'))
TRUE
perfect...
> sapply(c('not_available', 'testthat'), require, warn.conflicts = FALSE, quietly = TRUE)
not_available testthat
FALSE FALSE
Warning messages:
1: In if (!loaded) { :
the condition has length > 1 and only the first element will be used
2: In if (!loaded) { :
the condition has length > 1 and only the first element will be used
Wuuut...
why does it warn us? And why is the output incorrect?
> sapply(c('not_available', 'testthat'), function(x) {x})
not_available testthat
"not_available" "testthat"
Oke, so sapply is not betraying me...
> sapply(c('not_available', 'testthat'), function(pkg) {require(pkg, warn.conflicts = FALSE, quietly = TRUE)})
not_available testthat
FALSE FALSE
Eeeh, now the warning is gone, but the answer.... still wrong... why?
Any clue? Expected behaviour would be a returned value with [FALSE TRUE] (relating to 'not_available' and 'testthat').
Solution 1:[1]
Alright, it is due to the special 'library' and 'require' behaviour to also work with unquoted values. So the following will demonstrate the failure:
pkgs <- 'testthat'
require(pkgs)
Loading required package: pkgs
Warning message:
In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
there is no package called ‘pkgs’
The solution is to provide 'character.only'
sapply(c('not_available', 'testthat'), require, character.only = TRUE)
not_available testthat
FALSE TRUE
works just fine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
