For one of my scripts I want to write an R function that checks if a package is already installed: if so it should use library() to import it in the namespace, otherwise it should install it and import it.
I assumed that pkgname is a string and tried to write something like:
ensure_library <- function(pkgname) {
if (!require(pkgname)) {
install.packages(pkgname, dependencies = TRUE)
}
require(pkgname)
}
As simple as is this function does not work.
If I try to run it like ensure_library("dplyr")
it installs the package dplyr but then it fails because it trys to import pkgname
rather than dplyr
in the namespace.
ensure_library("dplyr")
Loading required package: pkgname
Installing package into ‘/home/luca/R-dev’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/src/contrib/dplyr_0.5.0.tar.gz'
Content type 'application/x-gzip' length 708476 bytes (691 KB)
==================================================
downloaded 691 KB
* installing *source* package ‘dplyr’ ...
** package ‘dplyr’ successfully unpacked and MD5 sums checked
** libs
.... a lot of compiling here....
installing to /home/luca/R-dev/dplyr/libs
** R
** data
*** moving datasets to lazyload DB
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded
* DONE (dplyr)
The downloaded source packages are in
‘/tmp/Rtmpfd2Lep/downloaded_packages’
Loading required package: pkgname
Warning messages:
1: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
there is no package called ‘pkgname’
2: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
there is no package called ‘pkgname’
Also, if I now re-run it it will install dplyr
once again.
I realize this is probably due to R non-standard-evaluation and I have tried several combination of eval/substitute/quote in order to make it work with require
but I couldn't succeed.
Can somebody help me understanding what is going on and if there is some easy-fix?
If a function already implementing this exists I would like to know, but what I am really interested is understanding why my code does not work as intended.