1

I've visited the question on how to implement a script for checking whether the proper packages are loaded but none of them work when I've tried to modify the code to do other things e.g., load the listed package if it is already installed or take a list of packages rather than having to enter them one by one.

What I've tried:

# works for checking whether individual packages are installed and if not 
# installing them (wrapped in a function to save space)

    chinst <- function(x){if(x %in% rownames(installed.packages())==FALSE) {install.packages(x)}}
    chinst("car")

# (NOT functioning) can't add an `library()` to the if function

    chinst2 <- function(x){if(x %in% rownames(installed.packages())==FALSE) {if(x %in% rownames(available.packages())==FALSE) {paste(x,"is not a valid package name via CRAN")} else {install.packages(x)}} else {library(x)}}

# (NOT Functioning) check a list of packages rather than individual ones

    pkgs <- list("MCMCpack", "BMA", "coda")
    lapply(X = pkgs, FUN = chinst)
cmbarbu
  • 4,354
  • 25
  • 45
timothy.s.lau
  • 1,001
  • 1
  • 10
  • 22
  • Typically one uses `if(!require(package)) install.packages(package)` for an operation like this, as `require()` returns a logical result for if the package loads successfully or not – Rich Scriven Mar 25 '15 at 16:13
  • Writing that repeatedly to install and then load packages when you end up using 5-10 packages seems excessive. If I can get a function to work right I can add it to my R profile and use maybe one or two lines. – timothy.s.lau Mar 25 '15 at 16:15
  • Well either way, having `%in%` in the `if()` statement will likely cause problems (warnings and unintended results) as well. You could use `any()` to be safe, then something like `if(any(x %in% y)) lapply(x[x %in% y], library, character.only = TRUE)` or something along those lines. I'm pretty sure you can use a vector of any length in `install.packages()` too – Rich Scriven Mar 25 '15 at 16:17

1 Answers1

2

I think something like this might work for you. Instead of a list of package names for pkgs, use a character vector.

fun <- function(pkgs) {
    ## check for installed packages
    have <- pkgs %in% rownames(installed.packages())
    ## if we don't have them all, install the ones we don't have
    if(!all(have)) install.packages(pkgs[!have]) 
    ## load them all
    invisible(lapply(pkgs, require, character.only = TRUE))
}

fun(c("MCMCpack", "BMA", "coda"))

Note that depending on the setup of your .libPaths(), using .packages(TRUE) generally will return the same as rownames(installed.packages()) and is a lot faster.

Also note that, for me, rownames(installed.packages()) has not been reliable. See this Q&A

Community
  • 1
  • 1
Rich Scriven
  • 97,041
  • 11
  • 181
  • 245
  • Check if a package is installed, if not install it then load it, if so, just load it. Multiple birds one stone. – timothy.s.lau Mar 25 '15 at 16:40
  • If I removed what came after the else it wouldn't have "library" any more and wouldn't load the package if it were already installed. Right? If the package is already installed I just want the function to load it. – timothy.s.lau Mar 25 '15 at 16:44
  • Nice answer although I was really confused by `Negate(any)(have)` at first glance! – talat Mar 25 '15 at 16:44
  • I would say yes, it looks much easier to read (but that may be very subjective..) – talat Mar 25 '15 at 16:47
  • Also, if you could rewrite it as a function for other people to use I think it'd be a more useful answer. – timothy.s.lau Mar 25 '15 at 16:48
  • Btw, isn't this kind of a case for `require`? – talat Mar 25 '15 at 16:48
  • It prints out the loaded packages for each package you list (kinda messy) @RichardScriven it loads the packages if they are already installed but it doesn't install them if they aren't. So I guess this isn't a solution. – timothy.s.lau Mar 25 '15 at 16:54
  • The addition as well, after deleting MCMCpack, when I run these it doesn't re-install. – timothy.s.lau Mar 25 '15 at 16:57
  • after uninstalling MCMCpack and running the updated function I get: `fun(c("MCMCpack", "BMA", "coda")) [[1]] [1] TRUE [[2]] [1] TRUE [[3]] [1] TRUE` – timothy.s.lau Mar 25 '15 at 17:02
  • Nevermind, restarted Rstudio and it ran fine. @RichardScriven, this deserves a bounty. Thanks for tackling that (countless hours saved). – timothy.s.lau Mar 25 '15 at 17:05