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:
# 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').
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.