18

Our R scripts are used on multiple users on multiple computers and hence there are deviations in which packages are installed on each computer. To ensure that each script works for all users I would like to define a function pkgLoad which will first test if the package is installed locally before loading the library with suppressed startup messages. Using Check for installed packages before running install.packages() as a guide, I tried

 pkgLoad <- function(x)
  {
    if (!require(x,character.only = TRUE))
    {
      install.packages(x,dep=TRUE, repos='http://star-www.st-andrews.ac.uk/cran/')
      if(!require(x,character.only = TRUE)) stop("Package not found")
    }
    #now load library and suppress warnings
    suppressPackageStartupMessages(library(x))
    library(x)
  }

When I try to load ggplot2 using pkgLoad("ggplot2") I get the following error message in my terminal

Error in paste("package", package, sep = ":") : object 'ggplot2' not found > pkgLoad("ggplot2") Loading required package: ggplot2 Error in library(x) : there is no package called ‘x’ > pkgLoad("ggplot2") Error in library(x) : there is no package called ‘x’

Any why x changes from ggplot2 to plain old x?

xilliam
  • 2,074
  • 2
  • 15
  • 27
moadeep
  • 3,988
  • 10
  • 45
  • 72
  • 3
    Looks to me like those last two calls to `library` are redundant -- at that point the package should be loaded already if it exists. – Lars Kotthoff Mar 01 '13 at 11:04

6 Answers6

17

I wrote this function the other day that I thought would be useful...

install_load <- function (package1, ...)  {   

   # convert arguments to vector
   packages <- c(package1, ...)

   # start loop to determine if each package is installed
   for(package in packages){

       # if package is installed locally, load
       if(package %in% rownames(installed.packages()))
          do.call('library', list(package))

       # if package is not installed locally, download, then load
       else {
          install.packages(package)
          do.call("library", list(package))
       }
   } 
}
maloneypatr
  • 3,562
  • 4
  • 23
  • 33
  • 2
    Thank you creating this function. I have made some changes to the function and released it on GitHub (https://github.com/iembry-USGS/install.load). – iembry Apr 30 '15 at 19:42
  • 2
    You're very welcome. My next step will be to have the package released to CRAN. – iembry May 01 '15 at 01:03
  • 2
    The package repository has been changed to https://gitlab.com/iembry/install.load. It is also located in CRAN. I will be making another update to the package soon. – iembry Jan 12 '16 at 07:15
14

The CRAN pacman package that I maintain can address this nicely. Using the following header (to ensure pacman is installed first) and then the p_load function will try to load the package and then get them from CRAN if R can't load the package.

if (!require("pacman")) install.packages("pacman"); library(pacman)
p_load(qdap, ggplot2, fakePackage, dplyr, tidyr)
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
7

Use library(x,character.only=TRUE). Also you don't need the last line as suppressPackageStartupMessages(library(x,character.only=TRUE)) already loads the package.

EDIT: @LarsKotthoff is right, you already load the package inside of the if brackets. There you already use option character.only=TRUE so everything is good if you just remove last to lines of your function body.

Jouni Helske
  • 6,427
  • 29
  • 52
3

Have a look at this nice function: klick

EDi
  • 13,160
  • 2
  • 48
  • 57
2

The following can be used:

check.and.install.Package<-function(package_name){
    if(!package_name%in%installed.packages()){
        install.packages(package_name)
    }
}

check.and.install.Package("RTextTools")
check.and.install.Package("e1071")
served_raw
  • 92
  • 5
1

Though @maloneypatr function works fine, but it is quite silent and does not respond on success of packages loaded. I built below function that does make some checks on user entry and also respond on the number of packages being successfully installed.

lubripack <- function(...,silent=FALSE){

  #check names and run 'require' function over if the given package is installed
  requirePkg<- function(pkg){if(length(setdiff(pkg,rownames(installed.packages())))==0)
                                    require(pkg, quietly = TRUE,character.only = TRUE)
                            }

  packages <- as.vector(unlist(list(...)))
  if(!is.character(packages))stop("No numeric allowed! Input must contain package names to install and load")

  if (length(setdiff(packages,rownames(installed.packages()))) > 0 )
     install.packages(setdiff(packages,rownames(installed.packages())),
                      repos = c("https://cran.revolutionanalytics.com/", "http://owi.usgs.gov/R/"))

  res<- unlist(sapply(packages, requirePkg))

  if(silent == FALSE && !is.null(res)) {cat("\nBellow Packages Successfully Installed:\n\n")
                    print(res)
                   }
}

Note 1:

If silent = TRUE(all capital silent), it installs and loads packages without reporting. If silent = FALSE, it reports successful installation of packages. Default value is silent = FALSE

How to use

lubripack(“pkg1","pkg2",.,.,.,.,"pkg")

Example 1: When all packages are valid and mode is not silent

lubripack(“shiny","ggvis")

or

lubripack(“shiny","ggvis", silent = FALSE)

Output

enter image description here

Example 2: When all packages are valid and mode is silent

lubripack(“caret","ggvis","tm", silent = TRUE) 

Output 2

enter image description here

Example 3: When package cannot be found

lubripack(“shiny","ggvis","invalidpkg", silent=FALSE) 

Output 3

enter image description here


How to Install Package:

Run below code to download the package and install it from GitHub. No need to have GitHub Account.

library(devtools)
install_github("espanta/lubripack")
Espanta
  • 1,080
  • 1
  • 17
  • 27