Installing all CRAN packages that are not already installed? - r

The following R commands will install all CRAN packages:
availablePackages <- available.packages()[,1]
install.packages(availablePackages)
And the following command will list all installed packages:
installedPackages <- .packages(all.available = TRUE)
My question is: How do I instruct R to install all CRAN packages that are not already installed?

Frankly, I think it's painstaking job... it would last for days, even weeks (depending on resources), but here's the code (I just enjoy doing trivial things):
# get names of installed packages
packs <- installed.packages()
exc <- names(packs[,'Package'])
# get available package names
av <- names(available.packages()[,1])
# create loooong string
ins <- av[!av %in% exc]
install.packages(ins)
I still don't get why you're doing this, but, hey... some things are just not meant to be....
What wonders me the most is the fact that you've already answered your own question! You got what you needed, and it's just up to you to put things together...
Are we missing the point? Did you have something else in mind?!?

1) Why would you want to do that? There are over 3500 (as of Feb 2012) of them?
2) Did you look at CRAN Task Views and the ctv package that allows you to install packages from a given task?
3) You bold-face question is a simple indexing query you can do by hand (and besides that, also see help(sets))
R> available <- LETTERS # a simple set
R> installed <- LETTERS[c(1:10, 15:26)] # a simple subset
R> available[ ! available %in% installed ]
[1] "K" "L" "M" "N"
R>
Edit: in response to your follow-up:
a) If a package does not pass 'R CMD check' on Linux and Windows, it does not get uploaded to CRAN. So that job is done.
b) Getting all depends at your end is work too as you will see. We did it for cran2deb which is at http://debian.cran.r-project.org (which does full-blown Debian package building which is more than just installing). We get about 2050 out of 2150 packages built. There are a few we refuse to build because of license, a few we cannot because of missing headers or libs and a few we cannot build because they need e.g. BioConductor packages.

type this command and then all packages will be installed automatically:
install.packages(available.packages()[,1])

Better if you use:
check.and.install.Package<-function(package_name){
if(!package_name%in%installed.packages()){
install.packages(package_name)
}
}
call the function and check if required package is installed:
check.and.install.Package("pkgName")

I've tested this and it works
availablePackages=available.packages()
availablePackages<-as.vector(availablePackages[,1])
installedPackages=.packages(all.available = TRUE)
missedPackages<-setdiff(availablePackages, installedPackages)
for (i in 1:length(missedPackages))
{
pkgName <- missedPackages[i]
install.packages(pkgName)
}
print("END")
Regards

From my experience, it is not wise to install all the R packages at once! Even if you do not call upon (using library function) all those packages, by just sitting in the home directory, they can slow down your R studio. At least that's what happened in my case.

Related

How to write a function that can load R package, if this package is not installed, install it automatically [duplicate]

I seem to be sharing a lot of code with coauthors these days. Many of them are novice/intermediate R users and don't realize that they have to install packages they don't already have.
Is there an elegant way to call installed.packages(), compare that to the ones I am loading and install if missing?
Yes. If you have your list of packages, compare it to the output from installed.packages()[,"Package"] and install the missing packages. Something like this:
list.of.packages <- c("ggplot2", "Rcpp")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)
Otherwise:
If you put your code in a package and make them dependencies, then they will automatically be installed when you install your package.
Dason K. and I have the pacman package that can do this nicely. The function p_load in the package does this. The first line is just to ensure that pacman is installed.
if (!require("pacman")) install.packages("pacman")
pacman::p_load(package1, package2, package_n)
You can just use the return value of require:
if(!require(somepackage)){
install.packages("somepackage")
library(somepackage)
}
I use library after the install because it will throw an exception if the install wasn't successful or the package can't be loaded for some other reason. You make this more robust and reuseable:
dynamic_require <- function(package){
if(eval(parse(text=paste("require(",package,")")))) return(TRUE)
install.packages(package)
return(eval(parse(text=paste("require(",package,")"))))
}
The downside to this method is that you have to pass the package name in quotes, which you don't do for the real require.
A lot of the answers above (and on duplicates of this question) rely on installed.packages which is bad form. From the documentation:
This can be slow when thousands of packages are installed, so do not use this to find out if a named package is installed (use system.file or find.package) nor to find out if a package is usable (call require and check the return value) nor to find details of a small number of packages (use packageDescription). It needs to read several files per installed package, which will be slow on Windows and on some network-mounted file systems.
So, a better approach is to attempt to load the package using require and and install if loading fails (require will return FALSE if it isn't found). I prefer this implementation:
using<-function(...) {
libs<-unlist(list(...))
req<-unlist(lapply(libs,require,character.only=TRUE))
need<-libs[req==FALSE]
if(length(need)>0){
install.packages(need)
lapply(need,require,character.only=TRUE)
}
}
which can be used like this:
using("RCurl","ggplot2","jsonlite","magrittr")
This way it loads all the packages, then goes back and installs all the missing packages (which if you want, is a handy place to insert a prompt to ask if the user wants to install packages). Instead of calling install.packages separately for each package it passes the whole vector of uninstalled packages just once.
Here's the same function but with a windows dialog that asks if the user wants to install the missing packages
using<-function(...) {
libs<-unlist(list(...))
req<-unlist(lapply(libs,require,character.only=TRUE))
need<-libs[req==FALSE]
n<-length(need)
if(n>0){
libsmsg<-if(n>2) paste(paste(need[1:(n-1)],collapse=", "),",",sep="") else need[1]
print(libsmsg)
if(n>1){
libsmsg<-paste(libsmsg," and ", need[n],sep="")
}
libsmsg<-paste("The following packages could not be found: ",libsmsg,"\n\r\n\rInstall missing packages?",collapse="")
if(winDialog(type = c("yesno"), libsmsg)=="YES"){
install.packages(need)
lapply(need,require,character.only=TRUE)
}
}
}
if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')
"ggplot2" is the package. It checks to see if the package is installed, if it is not it installs it. It then loads the package regardless of which branch it took.
TL;DR you can use find.package() for this.
Almost all the answers here rely on either (1) require() or (2) installed.packages() to check if a given package is already installed or not.
I'm adding an answer because these are unsatisfactory for a lightweight approach to answering this question.
require has the side effect of loading the package's namespace, which may not always be desirable
installed.packages is a bazooka to light a candle -- it will check the universe of installed packages first, then we check if our one (or few) package(s) are "in stock" at this library. No need to build a haystack just to find a needle.
This answer was also inspired by #ArtemKlevtsov's great answer in a similar spirit on a duplicated version of this question. He noted that system.file(package=x) can have the desired affect of returning '' if the package isn't installed, and something with nchar > 1 otherwise.
If we look under the hood of how system.file accomplishes this, we can see it uses a different base function, find.package, which we could use directly:
# a package that exists
find.package('data.table', quiet=TRUE)
# [1] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/data.table"
# a package that does not
find.package('InstantaneousWorldPeace', quiet=TRUE)
# character(0)
We can also look under the hood at find.package to see how it works, but this is mainly an instructive exercise -- the only ways to slim down the function that I see would be to skip some robustness checks. But the basic idea is: look in .libPaths() -- any installed package pkg will have a DESCRIPTION file at file.path(.libPaths(), pkg), so a quick-and-dirty check is file.exists(file.path(.libPaths(), pkg, 'DESCRIPTION').
This solution will take a character vector of package names and attempt to load them, or install them if loading fails. It relies on the return behaviour of require to do this because...
require returns (invisibly) a logical indicating whether the required package is available
Therefore we can simply see if we were able to load the required package and if not, install it with dependencies. So given a character vector of packages you wish to load...
foo <- function(x){
for( i in x ){
# require returns TRUE invisibly if it was able to load package
if( ! require( i , character.only = TRUE ) ){
# If package was not able to be loaded then re-install
install.packages( i , dependencies = TRUE )
# Load package after installing
require( i , character.only = TRUE )
}
}
}
# Then try/install packages...
foo( c("ggplot2" , "reshape2" , "data.table" ) )
Although the answer of Shane is really good, for one of my project I needed to remove the ouput messages, warnings and install packages automagically. I have finally managed to get this script:
InstalledPackage <- function(package)
{
available <- suppressMessages(suppressWarnings(sapply(package, require, quietly = TRUE, character.only = TRUE, warn.conflicts = FALSE)))
missing <- package[!available]
if (length(missing) > 0) return(FALSE)
return(TRUE)
}
CRANChoosen <- function()
{
return(getOption("repos")["CRAN"] != "#CRAN#")
}
UsePackage <- function(package, defaultCRANmirror = "http://cran.at.r-project.org")
{
if(!InstalledPackage(package))
{
if(!CRANChoosen())
{
chooseCRANmirror()
if(!CRANChoosen())
{
options(repos = c(CRAN = defaultCRANmirror))
}
}
suppressMessages(suppressWarnings(install.packages(package)))
if(!InstalledPackage(package)) return(FALSE)
}
return(TRUE)
}
Use:
libraries <- c("ReadImages", "ggplot2")
for(library in libraries)
{
if(!UsePackage(library))
{
stop("Error!", library)
}
}
# List of packages for session
.packages = c("ggplot2", "plyr", "rms")
# Install CRAN packages (if not already installed)
.inst <- .packages %in% installed.packages()
if(length(.packages[!.inst]) > 0) install.packages(.packages[!.inst])
# Load packages into session
lapply(.packages, require, character.only=TRUE)
Use packrat so that the shared libraries are exactly the same and not changing other's environment.
In terms of elegance and best practice I think you're fundamentally going about it the wrong way. The package packrat was designed for these issues. It is developed by RStudio by Hadley Wickham. Instead of them having to install dependencies and possibly mess up someone's environment system, packrat uses its own directory and installs all the dependencies for your programs in there and doesn't touch someone's environment.
Packrat is a dependency management system for R.
R package dependencies can be frustrating. Have you ever had to use trial-and-error to figure out what R packages you need to install to make someone else’s code work–and then been left with those packages globally installed forever, because now you’re not sure whether you need them? Have you ever updated a package to get code in one of your projects to work, only to find that the updated package makes code in another project stop working?
We built packrat to solve these problems. Use packrat to make your R projects more:
Isolated: Installing a new or updated package for one project won’t break your other projects, and vice versa. That’s because packrat gives each project its own private package library.
Portable: Easily transport your projects from one computer to another, even across different platforms. Packrat makes it easy to install the packages your project depends on.
Reproducible: Packrat records the exact package versions you depend on, and ensures those exact versions are the ones that get installed wherever you go.
https://rstudio.github.io/packrat/
This is the purpose of the rbundler package: to provide a way to control the packages that are installed for a specific project. Right now the package works with the devtools functionality to install packages to your project's directory. The functionality is similar to Ruby's bundler.
If your project is a package (recommended) then all you have to do is load rbundler and bundle the packages. The bundle function will look at your package's DESCRIPTION file to determine which packages to bundle.
library(rbundler)
bundle('.', repos="http://cran.us.r-project.org")
Now the packages will be installed in the .Rbundle directory.
If your project isn't a package, then you can fake it by creating a DESCRIPTION file in your project's root directory with a Depends field that lists the packages that you want installed (with optional version information):
Depends: ggplot2 (>= 0.9.2), arm, glmnet
Here's the github repo for the project if you're interested in contributing: rbundler.
You can simply use the setdiff function to get the packages that aren't installed and then install them. In the sample below, we check if the ggplot2 and Rcpp packages are installed before installing them.
unavailable <- setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages()))
install.packages(unavailable)
In one line, the above can be written as:
install.packages(setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages())))
The current version of RStudio (>=1.2) includes a feature to detect missing packages in library() and require() calls, and prompts the user to install them:
Detect missing R packages
Many R scripts open with calls to library() and require() to load the packages they need in order to execute. If you open an R script that references packages that you don’t have installed, RStudio will now offer to install all the needed packages in a single click. No more typing install.packages() repeatedly until the errors go away!
https://blog.rstudio.com/2018/11/19/rstudio-1-2-preview-the-little-things/
This seems to address the original concern of OP particularly well:
Many of them are novice/intermediate R users and don't realize that they have to install packages they don't already have.
Sure.
You need to compare 'installed packages' with 'desired packages'. That's very close to what I do with CRANberries as I need to compare 'stored known packages' with 'currently known packages' to determine new and/or updated packages.
So do something like
AP <- available.packages(contrib.url(repos[i,"url"])) # available t repos[i]
to get all known packages, simular call for currently installed packages and compare that to a given set of target packages.
The following simple function works like a charm:
usePackage<-function(p){
# load a package if installed, else load after installation.
# Args:
# p: package name in quotes
if (!is.element(p, installed.packages()[,1])){
print(paste('Package:',p,'Not found, Installing Now...'))
install.packages(p, dep = TRUE)}
print(paste('Loading Package :',p))
require(p, character.only = TRUE)
}
(not mine, found this on the web some time back and had been using it since then. not sure of the original source)
I use following function to install package if require("<package>") exits with package not found error. It will query both - CRAN and Bioconductor repositories for missing package.
Adapted from the original work by Joshua Wiley,
http://r.789695.n4.nabble.com/Install-package-automatically-if-not-there-td2267532.html
install.packages.auto <- function(x) {
x <- as.character(substitute(x))
if(isTRUE(x %in% .packages(all.available=TRUE))) {
eval(parse(text = sprintf("require(\"%s\")", x)))
} else {
#update.packages(ask= FALSE) #update installed packages.
eval(parse(text = sprintf("install.packages(\"%s\", dependencies = TRUE)", x)))
}
if(isTRUE(x %in% .packages(all.available=TRUE))) {
eval(parse(text = sprintf("require(\"%s\")", x)))
} else {
source("http://bioconductor.org/biocLite.R")
#biocLite(character(), ask=FALSE) #update installed packages.
eval(parse(text = sprintf("biocLite(\"%s\")", x)))
eval(parse(text = sprintf("require(\"%s\")", x)))
}
}
Example:
install.packages.auto(qvalue) # from bioconductor
install.packages.auto(rNMF) # from CRAN
PS: update.packages(ask = FALSE) & biocLite(character(), ask=FALSE) will update all installed packages on the system. This can take a long time and consider it as a full R upgrade which may not be warranted all the time!
Today, I stumbled on two handy function provided by the rlang package, namely, is_installed() and check_installed().
From the help page (emphasis added):
These functions check that packages are installed with minimal side effects. If installed, the packages will be loaded but not attached.
is_installed() doesn't interact with the user. It simply returns TRUE or FALSE depending on whether the packages are installed.
In interactive sessions, check_installed() asks the user whether to install missing packages. If the user accepts, the packages are installed [...]. If the session is non interactive or if the user chooses not to install the packages, the current evaluation is aborted.
interactive()
#> [1] FALSE
rlang::is_installed(c("dplyr"))
#> [1] TRUE
rlang::is_installed(c("foobarbaz"))
#> [1] FALSE
rlang::check_installed(c("dplyr"))
rlang::check_installed(c("foobarbaz"))
#> Error:
#> ! The package `foobarbaz` is required.
Created on 2022-03-25 by the reprex package (v2.0.1)
I have implemented the function to install and load required R packages silently. Hope might help. Here is the code:
# Function to Install and Load R Packages
Install_And_Load <- function(Required_Packages)
{
Remaining_Packages <- Required_Packages[!(Required_Packages %in% installed.packages()[,"Package"])];
if(length(Remaining_Packages))
{
install.packages(Remaining_Packages);
}
for(package_name in Required_Packages)
{
library(package_name,character.only=TRUE,quietly=TRUE);
}
}
# Specify the list of required packages to be installed and load
Required_Packages=c("ggplot2", "Rcpp");
# Call the Function
Install_And_Load(Required_Packages);
Quite basic one.
pkgs = c("pacman","data.table")
if(length(new.pkgs <- setdiff(pkgs, rownames(installed.packages())))) install.packages(new.pkgs)
Thought I'd contribute the one I use:
testin <- function(package){if (!package %in% installed.packages())
install.packages(package)}
testin("packagename")
Regarding your main objective " to install libraries they don't already have. " and regardless of using " instllaed.packages() ". The following function mask the original function of require. It tries to load and check the named package "x" , if it's not installed, install it directly including dependencies; and lastly load it normaly. you rename the function name from 'require' to 'library' to maintain integrity . The only limitation is packages names should be quoted.
require <- function(x) {
if (!base::require(x, character.only = TRUE)) {
install.packages(x, dep = TRUE) ;
base::require(x, character.only = TRUE)
}
}
So you can load and installed package the old fashion way of R.
require ("ggplot2")
require ("Rcpp")
48 lapply_install_and_load <- function (package1, ...)
49 {
50 #
51 # convert arguments to vector
52 #
53 packages <- c(package1, ...)
54 #
55 # check if loaded and installed
56 #
57 loaded <- packages %in% (.packages())
58 names(loaded) <- packages
59 #
60 installed <- packages %in% rownames(installed.packages())
61 names(installed) <- packages
62 #
63 # start loop to determine if each package is installed
64 #
65 load_it <- function (p, loaded, installed)
66 {
67 if (loaded[p])
68 {
69 print(paste(p, "loaded"))
70 }
71 else
72 {
73 print(paste(p, "not loaded"))
74 if (installed[p])
75 {
76 print(paste(p, "installed"))
77 do.call("library", list(p))
78 }
79 else
80 {
81 print(paste(p, "not installed"))
82 install.packages(p)
83 do.call("library", list(p))
84 }
85 }
86 }
87 #
88 lapply(packages, load_it, loaded, installed)
89 }
source("https://bioconductor.org/biocLite.R")
if (!require("ggsci")) biocLite("ggsci")
Using lapply family and anonymous function approach you may:
Try to attach all listed packages.
Install missing only (using || lazy evaluation).
Attempt to attach again those were missing in step 1 and installed in step 2.
Print each package final load status (TRUE / FALSE).
req <- substitute(require(x, character.only = TRUE))
lbs <- c("plyr", "psych", "tm")
sapply(lbs, function(x) eval(req) || {install.packages(x); eval(req)})
plyr psych tm
TRUE TRUE TRUE
I use the following which will check if package is installed and if dependencies are updated, then loads the package.
p<-c('ggplot2','Rcpp')
install_package<-function(pack)
{if(!(pack %in% row.names(installed.packages())))
{
update.packages(ask=F)
install.packages(pack,dependencies=T)
}
require(pack,character.only=TRUE)
}
for(pack in p) {install_package(pack)}
completeFun <- function(data, desiredCols) {
completeVec <- complete.cases(data[, desiredCols])
return(data[completeVec, ])
}
Here's my code for it:
packages <- c("dplyr", "gridBase", "gridExtra")
package_loader <- function(x){
for (i in 1:length(x)){
if (!identical((x[i], installed.packages()[x[i],1])){
install.packages(x[i], dep = TRUE)
} else {
require(x[i], character.only = TRUE)
}
}
}
package_loader(packages)
library <- function(x){
x = toString(substitute(x))
if(!require(x,character.only=TRUE)){
install.packages(x)
base::library(x,character.only=TRUE)
}}
This works with unquoted package names and is fairly elegant (cf. GeoObserver's answer)
In my case, I wanted a one liner that I could run from the commandline (actually via a Makefile). Here is an example installing "VGAM" and "feather" if they are not already installed:
R -e 'for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")'
From within R it would just be:
for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")
There is nothing here beyond the previous solutions except that:
I keep it to a single line
I hard code the repos parameter (to avoid any popups asking about the mirror to use)
I don't bother to define a function to be used elsewhere
Also note the important character.only=TRUE (without it, the require would try to load the package p).
Let me share a bit of madness:
c("ggplot2","ggsci", "hrbrthemes", "gghighlight", "dplyr") %>% # What will you need to load for this script?
(function (x) ifelse(t =!(x %in% installed.packages()),
install.packages(x[t]),
lapply(x, require)))
There is a new-ish package (I am a codeveloper), Require, that is intended to be part of a reproducible workflow, meaning the function produces the same output the first time it is run or subsequent times, i.e., the end-state is the same regardless of starting state. The following installs any missing packages (I include require = FALSE to strictly address the original question... normally I leave this on the default because I will generally want them loaded to the search path).
These two lines are at the top of every script I write (adjusting the package selection as necessary), allowing the script to be used by anybody in any condition (including any or all dependencies missing).
if (!require("Require")) install.packages("Require")
Require::Require(c("ggplot2", "Rcpp"), require = FALSE)
You can thus use this in your script or pass it anyone.

Using ifelse to install a package [duplicate]

I seem to be sharing a lot of code with coauthors these days. Many of them are novice/intermediate R users and don't realize that they have to install packages they don't already have.
Is there an elegant way to call installed.packages(), compare that to the ones I am loading and install if missing?
Yes. If you have your list of packages, compare it to the output from installed.packages()[,"Package"] and install the missing packages. Something like this:
list.of.packages <- c("ggplot2", "Rcpp")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)
Otherwise:
If you put your code in a package and make them dependencies, then they will automatically be installed when you install your package.
Dason K. and I have the pacman package that can do this nicely. The function p_load in the package does this. The first line is just to ensure that pacman is installed.
if (!require("pacman")) install.packages("pacman")
pacman::p_load(package1, package2, package_n)
You can just use the return value of require:
if(!require(somepackage)){
install.packages("somepackage")
library(somepackage)
}
I use library after the install because it will throw an exception if the install wasn't successful or the package can't be loaded for some other reason. You make this more robust and reuseable:
dynamic_require <- function(package){
if(eval(parse(text=paste("require(",package,")")))) return(TRUE)
install.packages(package)
return(eval(parse(text=paste("require(",package,")"))))
}
The downside to this method is that you have to pass the package name in quotes, which you don't do for the real require.
A lot of the answers above (and on duplicates of this question) rely on installed.packages which is bad form. From the documentation:
This can be slow when thousands of packages are installed, so do not use this to find out if a named package is installed (use system.file or find.package) nor to find out if a package is usable (call require and check the return value) nor to find details of a small number of packages (use packageDescription). It needs to read several files per installed package, which will be slow on Windows and on some network-mounted file systems.
So, a better approach is to attempt to load the package using require and and install if loading fails (require will return FALSE if it isn't found). I prefer this implementation:
using<-function(...) {
libs<-unlist(list(...))
req<-unlist(lapply(libs,require,character.only=TRUE))
need<-libs[req==FALSE]
if(length(need)>0){
install.packages(need)
lapply(need,require,character.only=TRUE)
}
}
which can be used like this:
using("RCurl","ggplot2","jsonlite","magrittr")
This way it loads all the packages, then goes back and installs all the missing packages (which if you want, is a handy place to insert a prompt to ask if the user wants to install packages). Instead of calling install.packages separately for each package it passes the whole vector of uninstalled packages just once.
Here's the same function but with a windows dialog that asks if the user wants to install the missing packages
using<-function(...) {
libs<-unlist(list(...))
req<-unlist(lapply(libs,require,character.only=TRUE))
need<-libs[req==FALSE]
n<-length(need)
if(n>0){
libsmsg<-if(n>2) paste(paste(need[1:(n-1)],collapse=", "),",",sep="") else need[1]
print(libsmsg)
if(n>1){
libsmsg<-paste(libsmsg," and ", need[n],sep="")
}
libsmsg<-paste("The following packages could not be found: ",libsmsg,"\n\r\n\rInstall missing packages?",collapse="")
if(winDialog(type = c("yesno"), libsmsg)=="YES"){
install.packages(need)
lapply(need,require,character.only=TRUE)
}
}
}
if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')
"ggplot2" is the package. It checks to see if the package is installed, if it is not it installs it. It then loads the package regardless of which branch it took.
TL;DR you can use find.package() for this.
Almost all the answers here rely on either (1) require() or (2) installed.packages() to check if a given package is already installed or not.
I'm adding an answer because these are unsatisfactory for a lightweight approach to answering this question.
require has the side effect of loading the package's namespace, which may not always be desirable
installed.packages is a bazooka to light a candle -- it will check the universe of installed packages first, then we check if our one (or few) package(s) are "in stock" at this library. No need to build a haystack just to find a needle.
This answer was also inspired by #ArtemKlevtsov's great answer in a similar spirit on a duplicated version of this question. He noted that system.file(package=x) can have the desired affect of returning '' if the package isn't installed, and something with nchar > 1 otherwise.
If we look under the hood of how system.file accomplishes this, we can see it uses a different base function, find.package, which we could use directly:
# a package that exists
find.package('data.table', quiet=TRUE)
# [1] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/data.table"
# a package that does not
find.package('InstantaneousWorldPeace', quiet=TRUE)
# character(0)
We can also look under the hood at find.package to see how it works, but this is mainly an instructive exercise -- the only ways to slim down the function that I see would be to skip some robustness checks. But the basic idea is: look in .libPaths() -- any installed package pkg will have a DESCRIPTION file at file.path(.libPaths(), pkg), so a quick-and-dirty check is file.exists(file.path(.libPaths(), pkg, 'DESCRIPTION').
This solution will take a character vector of package names and attempt to load them, or install them if loading fails. It relies on the return behaviour of require to do this because...
require returns (invisibly) a logical indicating whether the required package is available
Therefore we can simply see if we were able to load the required package and if not, install it with dependencies. So given a character vector of packages you wish to load...
foo <- function(x){
for( i in x ){
# require returns TRUE invisibly if it was able to load package
if( ! require( i , character.only = TRUE ) ){
# If package was not able to be loaded then re-install
install.packages( i , dependencies = TRUE )
# Load package after installing
require( i , character.only = TRUE )
}
}
}
# Then try/install packages...
foo( c("ggplot2" , "reshape2" , "data.table" ) )
Although the answer of Shane is really good, for one of my project I needed to remove the ouput messages, warnings and install packages automagically. I have finally managed to get this script:
InstalledPackage <- function(package)
{
available <- suppressMessages(suppressWarnings(sapply(package, require, quietly = TRUE, character.only = TRUE, warn.conflicts = FALSE)))
missing <- package[!available]
if (length(missing) > 0) return(FALSE)
return(TRUE)
}
CRANChoosen <- function()
{
return(getOption("repos")["CRAN"] != "#CRAN#")
}
UsePackage <- function(package, defaultCRANmirror = "http://cran.at.r-project.org")
{
if(!InstalledPackage(package))
{
if(!CRANChoosen())
{
chooseCRANmirror()
if(!CRANChoosen())
{
options(repos = c(CRAN = defaultCRANmirror))
}
}
suppressMessages(suppressWarnings(install.packages(package)))
if(!InstalledPackage(package)) return(FALSE)
}
return(TRUE)
}
Use:
libraries <- c("ReadImages", "ggplot2")
for(library in libraries)
{
if(!UsePackage(library))
{
stop("Error!", library)
}
}
# List of packages for session
.packages = c("ggplot2", "plyr", "rms")
# Install CRAN packages (if not already installed)
.inst <- .packages %in% installed.packages()
if(length(.packages[!.inst]) > 0) install.packages(.packages[!.inst])
# Load packages into session
lapply(.packages, require, character.only=TRUE)
Use packrat so that the shared libraries are exactly the same and not changing other's environment.
In terms of elegance and best practice I think you're fundamentally going about it the wrong way. The package packrat was designed for these issues. It is developed by RStudio by Hadley Wickham. Instead of them having to install dependencies and possibly mess up someone's environment system, packrat uses its own directory and installs all the dependencies for your programs in there and doesn't touch someone's environment.
Packrat is a dependency management system for R.
R package dependencies can be frustrating. Have you ever had to use trial-and-error to figure out what R packages you need to install to make someone else’s code work–and then been left with those packages globally installed forever, because now you’re not sure whether you need them? Have you ever updated a package to get code in one of your projects to work, only to find that the updated package makes code in another project stop working?
We built packrat to solve these problems. Use packrat to make your R projects more:
Isolated: Installing a new or updated package for one project won’t break your other projects, and vice versa. That’s because packrat gives each project its own private package library.
Portable: Easily transport your projects from one computer to another, even across different platforms. Packrat makes it easy to install the packages your project depends on.
Reproducible: Packrat records the exact package versions you depend on, and ensures those exact versions are the ones that get installed wherever you go.
https://rstudio.github.io/packrat/
This is the purpose of the rbundler package: to provide a way to control the packages that are installed for a specific project. Right now the package works with the devtools functionality to install packages to your project's directory. The functionality is similar to Ruby's bundler.
If your project is a package (recommended) then all you have to do is load rbundler and bundle the packages. The bundle function will look at your package's DESCRIPTION file to determine which packages to bundle.
library(rbundler)
bundle('.', repos="http://cran.us.r-project.org")
Now the packages will be installed in the .Rbundle directory.
If your project isn't a package, then you can fake it by creating a DESCRIPTION file in your project's root directory with a Depends field that lists the packages that you want installed (with optional version information):
Depends: ggplot2 (>= 0.9.2), arm, glmnet
Here's the github repo for the project if you're interested in contributing: rbundler.
You can simply use the setdiff function to get the packages that aren't installed and then install them. In the sample below, we check if the ggplot2 and Rcpp packages are installed before installing them.
unavailable <- setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages()))
install.packages(unavailable)
In one line, the above can be written as:
install.packages(setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages())))
The current version of RStudio (>=1.2) includes a feature to detect missing packages in library() and require() calls, and prompts the user to install them:
Detect missing R packages
Many R scripts open with calls to library() and require() to load the packages they need in order to execute. If you open an R script that references packages that you don’t have installed, RStudio will now offer to install all the needed packages in a single click. No more typing install.packages() repeatedly until the errors go away!
https://blog.rstudio.com/2018/11/19/rstudio-1-2-preview-the-little-things/
This seems to address the original concern of OP particularly well:
Many of them are novice/intermediate R users and don't realize that they have to install packages they don't already have.
Sure.
You need to compare 'installed packages' with 'desired packages'. That's very close to what I do with CRANberries as I need to compare 'stored known packages' with 'currently known packages' to determine new and/or updated packages.
So do something like
AP <- available.packages(contrib.url(repos[i,"url"])) # available t repos[i]
to get all known packages, simular call for currently installed packages and compare that to a given set of target packages.
The following simple function works like a charm:
usePackage<-function(p){
# load a package if installed, else load after installation.
# Args:
# p: package name in quotes
if (!is.element(p, installed.packages()[,1])){
print(paste('Package:',p,'Not found, Installing Now...'))
install.packages(p, dep = TRUE)}
print(paste('Loading Package :',p))
require(p, character.only = TRUE)
}
(not mine, found this on the web some time back and had been using it since then. not sure of the original source)
I use following function to install package if require("<package>") exits with package not found error. It will query both - CRAN and Bioconductor repositories for missing package.
Adapted from the original work by Joshua Wiley,
http://r.789695.n4.nabble.com/Install-package-automatically-if-not-there-td2267532.html
install.packages.auto <- function(x) {
x <- as.character(substitute(x))
if(isTRUE(x %in% .packages(all.available=TRUE))) {
eval(parse(text = sprintf("require(\"%s\")", x)))
} else {
#update.packages(ask= FALSE) #update installed packages.
eval(parse(text = sprintf("install.packages(\"%s\", dependencies = TRUE)", x)))
}
if(isTRUE(x %in% .packages(all.available=TRUE))) {
eval(parse(text = sprintf("require(\"%s\")", x)))
} else {
source("http://bioconductor.org/biocLite.R")
#biocLite(character(), ask=FALSE) #update installed packages.
eval(parse(text = sprintf("biocLite(\"%s\")", x)))
eval(parse(text = sprintf("require(\"%s\")", x)))
}
}
Example:
install.packages.auto(qvalue) # from bioconductor
install.packages.auto(rNMF) # from CRAN
PS: update.packages(ask = FALSE) & biocLite(character(), ask=FALSE) will update all installed packages on the system. This can take a long time and consider it as a full R upgrade which may not be warranted all the time!
Today, I stumbled on two handy function provided by the rlang package, namely, is_installed() and check_installed().
From the help page (emphasis added):
These functions check that packages are installed with minimal side effects. If installed, the packages will be loaded but not attached.
is_installed() doesn't interact with the user. It simply returns TRUE or FALSE depending on whether the packages are installed.
In interactive sessions, check_installed() asks the user whether to install missing packages. If the user accepts, the packages are installed [...]. If the session is non interactive or if the user chooses not to install the packages, the current evaluation is aborted.
interactive()
#> [1] FALSE
rlang::is_installed(c("dplyr"))
#> [1] TRUE
rlang::is_installed(c("foobarbaz"))
#> [1] FALSE
rlang::check_installed(c("dplyr"))
rlang::check_installed(c("foobarbaz"))
#> Error:
#> ! The package `foobarbaz` is required.
Created on 2022-03-25 by the reprex package (v2.0.1)
I have implemented the function to install and load required R packages silently. Hope might help. Here is the code:
# Function to Install and Load R Packages
Install_And_Load <- function(Required_Packages)
{
Remaining_Packages <- Required_Packages[!(Required_Packages %in% installed.packages()[,"Package"])];
if(length(Remaining_Packages))
{
install.packages(Remaining_Packages);
}
for(package_name in Required_Packages)
{
library(package_name,character.only=TRUE,quietly=TRUE);
}
}
# Specify the list of required packages to be installed and load
Required_Packages=c("ggplot2", "Rcpp");
# Call the Function
Install_And_Load(Required_Packages);
Quite basic one.
pkgs = c("pacman","data.table")
if(length(new.pkgs <- setdiff(pkgs, rownames(installed.packages())))) install.packages(new.pkgs)
Thought I'd contribute the one I use:
testin <- function(package){if (!package %in% installed.packages())
install.packages(package)}
testin("packagename")
Regarding your main objective " to install libraries they don't already have. " and regardless of using " instllaed.packages() ". The following function mask the original function of require. It tries to load and check the named package "x" , if it's not installed, install it directly including dependencies; and lastly load it normaly. you rename the function name from 'require' to 'library' to maintain integrity . The only limitation is packages names should be quoted.
require <- function(x) {
if (!base::require(x, character.only = TRUE)) {
install.packages(x, dep = TRUE) ;
base::require(x, character.only = TRUE)
}
}
So you can load and installed package the old fashion way of R.
require ("ggplot2")
require ("Rcpp")
48 lapply_install_and_load <- function (package1, ...)
49 {
50 #
51 # convert arguments to vector
52 #
53 packages <- c(package1, ...)
54 #
55 # check if loaded and installed
56 #
57 loaded <- packages %in% (.packages())
58 names(loaded) <- packages
59 #
60 installed <- packages %in% rownames(installed.packages())
61 names(installed) <- packages
62 #
63 # start loop to determine if each package is installed
64 #
65 load_it <- function (p, loaded, installed)
66 {
67 if (loaded[p])
68 {
69 print(paste(p, "loaded"))
70 }
71 else
72 {
73 print(paste(p, "not loaded"))
74 if (installed[p])
75 {
76 print(paste(p, "installed"))
77 do.call("library", list(p))
78 }
79 else
80 {
81 print(paste(p, "not installed"))
82 install.packages(p)
83 do.call("library", list(p))
84 }
85 }
86 }
87 #
88 lapply(packages, load_it, loaded, installed)
89 }
source("https://bioconductor.org/biocLite.R")
if (!require("ggsci")) biocLite("ggsci")
Using lapply family and anonymous function approach you may:
Try to attach all listed packages.
Install missing only (using || lazy evaluation).
Attempt to attach again those were missing in step 1 and installed in step 2.
Print each package final load status (TRUE / FALSE).
req <- substitute(require(x, character.only = TRUE))
lbs <- c("plyr", "psych", "tm")
sapply(lbs, function(x) eval(req) || {install.packages(x); eval(req)})
plyr psych tm
TRUE TRUE TRUE
I use the following which will check if package is installed and if dependencies are updated, then loads the package.
p<-c('ggplot2','Rcpp')
install_package<-function(pack)
{if(!(pack %in% row.names(installed.packages())))
{
update.packages(ask=F)
install.packages(pack,dependencies=T)
}
require(pack,character.only=TRUE)
}
for(pack in p) {install_package(pack)}
completeFun <- function(data, desiredCols) {
completeVec <- complete.cases(data[, desiredCols])
return(data[completeVec, ])
}
Here's my code for it:
packages <- c("dplyr", "gridBase", "gridExtra")
package_loader <- function(x){
for (i in 1:length(x)){
if (!identical((x[i], installed.packages()[x[i],1])){
install.packages(x[i], dep = TRUE)
} else {
require(x[i], character.only = TRUE)
}
}
}
package_loader(packages)
library <- function(x){
x = toString(substitute(x))
if(!require(x,character.only=TRUE)){
install.packages(x)
base::library(x,character.only=TRUE)
}}
This works with unquoted package names and is fairly elegant (cf. GeoObserver's answer)
In my case, I wanted a one liner that I could run from the commandline (actually via a Makefile). Here is an example installing "VGAM" and "feather" if they are not already installed:
R -e 'for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")'
From within R it would just be:
for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")
There is nothing here beyond the previous solutions except that:
I keep it to a single line
I hard code the repos parameter (to avoid any popups asking about the mirror to use)
I don't bother to define a function to be used elsewhere
Also note the important character.only=TRUE (without it, the require would try to load the package p).
Let me share a bit of madness:
c("ggplot2","ggsci", "hrbrthemes", "gghighlight", "dplyr") %>% # What will you need to load for this script?
(function (x) ifelse(t =!(x %in% installed.packages()),
install.packages(x[t]),
lapply(x, require)))
There is a new-ish package (I am a codeveloper), Require, that is intended to be part of a reproducible workflow, meaning the function produces the same output the first time it is run or subsequent times, i.e., the end-state is the same regardless of starting state. The following installs any missing packages (I include require = FALSE to strictly address the original question... normally I leave this on the default because I will generally want them loaded to the search path).
These two lines are at the top of every script I write (adjusting the package selection as necessary), allowing the script to be used by anybody in any condition (including any or all dependencies missing).
if (!require("Require")) install.packages("Require")
Require::Require(c("ggplot2", "Rcpp"), require = FALSE)
You can thus use this in your script or pass it anyone.

Uninstall (remove) R package with dependencies

I wanted to try some new package. I installed it, it required a lot of dependencies, so it installed plenty of other packages. I tried it and I am not impressed - now I would like to uninstall that package including all the dependencies!
Is there any way to remove given packages including all dependencies which are not needed by any other package in the system?
I looked at ?remove.packages but there is no option to do this.
Here is some code that will all you to remove a package and its unneeded dependencies. Note that its interpretation of "unneeded" dependent packages is the set of packages that this package depends on but that are not used in any other package. This means that it will also default to suggesting to uninstall packages that have no reverse dependencies. Thus I've implemented it as an interactive menu (like in update.packages) to give you control over what to uninstall.
library("tools")
removeDepends <- function(pkg, recursive = FALSE){
d <- package_dependencies(,installed.packages(), recursive = recursive)
depends <- if(!is.null(d[[pkg]])) d[[pkg]] else character()
needed <- unique(unlist(d[!names(d) %in% c(pkg,depends)]))
toRemove <- depends[!depends %in% needed]
if(length(toRemove)){
toRemove <- select.list(c(pkg,sort(toRemove)), multiple = TRUE,
title = "Select packages to remove")
remove.packages(toRemove)
return(toRemove)
} else {
invisible(character())
}
}
# Example
install.packages("YplantQMC") # installs an unneeded dependency "LeafAngle"
c("YplantQMC","LeafAngle") %in% installed.packages()[,1]
## [1] TRUE TRUE
removeDepends("YplantQMC")
c("YplantQMC","LeafAngle") %in% installed.packages()[,1]
## [1] FALSE FALSE
Note: The recursive option may be particularly useful. If package dependencies further depend on other unneeded packages, setting recursive = TRUE is vital. If dependencies are shallow (i.e., only one level down the dependency tree), this can be left as FALSE (the default).
There is in fact a function remove.packages() in base R, but it's in the package utils, which you need to load first:
library(utils)
remove.packages()
It's not entirely clear to me how much recursive cleanup this function does.
There are base R ways to handle this but I'm going to recommend a package (I know you're trying to get rid of these). I'm recommending this package for 2 reasons (1) it solves two problems you're having & (2) Dason K. and I are developing this package (full disclosure). This package's value stands in that the functions are easier to remember names that are consistent. It also does some combined operations. Note you could do all of this in base but this question is already pretty localized so thus I'm going to use a tool that makes answering easier.
This package will:
allow you to delete package and dependencies
allow you to install packages in a temporary directory rather than main library
The caveat is that you can't be 100% certain that the package dependency wasn't already there, installed by the user previously. Therefore I would take caution with every step of this solution that you're not deleting things that are of importance. This solution relies on 2 factors (1) pacman (2) file.info. We'll assume that dependencies that were modified within a certain (user defined) threshold of time are indeed unwanted packages. Note the word assume here.
I made this reproducible for the folks at home in that the answer will randomly install a package from CRAN with additional dependencies (this installs a package you do not already have locally with 3 or more dependencies; used random to not single out any package).
Making a reproducible example
library(pacman)
(available <- p_cran())
(randoms <- setdiff(available, p_lib()))
(mypackages <- p_lib())
ndeps <- 1
while(ndeps < 3) {
package <- sample(randoms, 1)
deps <- unlist(p_depends(package, character.only=TRUE), use.names=FALSE)
ndeps <- length(setdiff(deps, mypackages))
}
package
p_install(package, character.only = TRUE)
Uninstalling package
We will assign the package name from the first part to package or the OP can use the unwanted package they installed and assign that to package (my random package happened to be package <- "OrdinalLogisticBiplot"). This deletions process should, ideally, be done in a clean R session with no add-on packages (except pacman) loaded.
## function to grab file info date/time modified
infograb <- function(x) file.info(file.path(p_path(), x))[["mtime"]]
## determine the differences in times modified for "package"
## and all other packages in library
diffs <- as.numeric(infograb(package)) - sapply(p_lib(), infograb)
## user defined threshold
threshold <- 15
## determine packages just installed within the time frame of the unwanted package
(delete_deps <- diffs[diffs < threshold & diffs >= 0])
## recursively find all packages that could have been installed
potential_depends <- unlist(lapply(unlist(p_depends(package, character=TRUE)),
p_depends, character=TRUE, recursive=TRUE))
## delete packages that are both on the lists of (1) installed within time
## frame of unwanted package and a dependency of that package
p_delete(intersect(names(delete_deps), potential_depends), character.only = TRUE)
This approach makes some big assumptions.
A better approach from the get go
p_temp(package_to_try)
This allows you to try it out first and not have it muddy your local library.
If you're unimpressed with pacman you can use the method described above to delete it.
Here is a quick solution to have a look at the packages that are not required by any other locally installed packages.
library(pacman)
ip <- installed.packages()[,1]
deps <- lapply(1:length(ip), function(i) tryCatch(p_depends(ip[i], local = TRUE)$Imports, error = function(e) return(NULL)))
packages.on.which.things.depend <- sort(unique(unlist(deps)))
packages.on.which.nothing.depends <- setdiff(ip, packages.on.which.things.depend)
packages.on.which.nothing.depends
Then, have a quick look at it and remove the ones you are not using (just be careful and do not try to uninstall base).
After you have determined which ones you use and which you don’t use, you may proceed with something like
i.need <- c("AER", "car", "devtools", "glmnet", "gmm", "Hmisc", "pacman", "plm", "RcppArmadillo", "RcppEigen", "rmarkdown", "rugarch", "base", "datasets")
un <- setdiff(packages.on.which.nothing.depends, i.need)
un
remove.packages(un)
Rinse and repeat until there are no unneeded orphanes packages. R should not allow you to remove built-in system packages.

Check if R is running in RStudio

I am looking for a way to test if R is being run from RStudio. For some reason I could find the answer on google yesterday but not today, but I think it had to do with testing if a certain system variable was set.
This is from ?rstudio:
# Test whether running under RStudio
isRStudio <- Sys.getenv("RSTUDIO") == "1"
There is also rstudioapi::isAvailable(), but checking this is not as reliable because RStudio doesn't seem to really need the rstudioapi package to work correctly.
Check the .Platform$GUI option for "RStudio"
is.rstudio = function(){
.Platform$GUI == "RStudio"
}
See:
http://thecoatlessprofessor.com/programming/detecting-if-r-is-in-rstudio-and-changing-rstudios-default-graphing-device/
There is no "running inside RStudio". RStudio is merely an IDE layer that wraps around R; at the end of the day it just launches the normal R executable you need to have on your $PATH anyway to operate RStudio.
As a proxy, and as R Studio You could test available.packages() for the 'manipulate' package though, or as a shorter version see if RStudio added itself to the .libPaths() content:
R> any(grepl("RStudio", .libPaths()))
[1] TRUE
R>
R>
Edit in May 2020 or eight years later The question does come up, and one can query a variety of things from within. Here is an example from the terminal of RStudio:
$ env | grep -i rstudio | sort
GIO_LAUNCHED_DESKTOP_FILE=/usr/share/applications/rstudio.desktop
PATH=[...redacted...]
RMARKDOWN_MATHJAX_PATH=/usr/lib/rstudio/resources/mathjax-27
RS_RPOSTBACK_PATH=/usr/lib/rstudio/bin/rpostback
RSTUDIO=1
RSTUDIO_CONSOLE_COLOR=256
RSTUDIO_CONSOLE_WIDTH=111
RSTUDIO_PANDOC=/usr/lib/rstudio/bin/pandoc
RSTUDIO_PROGRAM_MODE=desktop
RSTUDIO_PROJ_NAME=chshli
RSTUDIO_SESSION_ID=9C62D3D4
RSTUDIO_SESSION_PORT=13494
RSTUDIO_TERM=2BD6BB88
RSTUDIO_USER_IDENTITY=edd
RSTUDIO_WINUTILS=bin/winutils
$
Similarly, from within the R session:
R> se <- Sys.getenv()
R> se[grepl("rstudio",se,ignore.case=TRUE)]
GIO_LAUNCHED_DESKTOP_FILE /usr/share/applications/rstudio.desktop
PATH [...also redacted...]
RMARKDOWN_MATHJAX_PATH /usr/lib/rstudio/resources/mathjax-27
RS_RPOSTBACK_PATH /usr/lib/rstudio/bin/rpostback
RSTUDIO_PANDOC /usr/lib/rstudio/bin/pandoc
R>
Edit in Aug 2021 or nine years later As all the answers listed here in the different answer may still be too much for people, you can also install package rstudioapi from CRAN and then ask it via rstudioapi::isAvailable() which comes back TRUE for me inside RStudio and FALSE in ESS / standard R.
When I start RStudio it seems to have tools:rstudio in position 2 on the search path. This has a function "RStudio.version" which is undocumented but seems to return the RStudio version string:
> RStudio.version()
[1] "0.96.316"
So you can define:
is.RStudio <- function(){
if(!exists("RStudio.version"))return(FALSE)
if(!is.function(RStudio.version))return(FALSE)
return(TRUE)
}
and maybe use that.
As of today, there are a few packages which include functions to check whether RStudio is running:
rstudioapi::isAvailable()
assertive::is_rstudio()
(list is non-exhaustive)
The assertive and assertive.reflections packages, resp., do include additional functions to check for other IDEs, desktop/server versions of RStudio, and various R releases (e.g., alpha, beta, devel, release, patched, etc.)
To add to the number of nice guesses, here is a message from 2011 (Ice Age)
http://support.rstudio.org/help/discussions/problems/413-location-of-installed-packages
if (Sys.getenv("RSTUDIO_USER_IDENTITY")!= ""){
.libPaths(.Library) # Avoid additional libraries } else { # not rstudio ...
I find the following works for me
checkRstudio <- function () {
return ("tools:rstudio" %in% search())
}
I am sort of new to R myself, but I believe Rstudio necessarily loads the
package "tools:rstudio" in order to run.
Neat solution is now available through the startup package via the is_rstudio_console function:
startup:::is_rstudio_console()
[1] TRUE
It may be worth adding that this function checks for two environment variables, RSTUDIO, which was mentioned in the answer by #krlmr and RSTUDIO_TERM that doesn't seem to be mentioned across the preceding answers at the moment.
function ()
{
(Sys.getenv("RSTUDIO") == "1") && !nzchar(Sys.getenv("RSTUDIO_TERM"))
}
The most reliable way to detect whether code is running in the main RStudio R session (without relying on the rstudioapi package) is:
commandArgs()[[1L]] == "RStudio"
Some comments on other answers:
Checking environment variables may be insufficient, as the "RSTUDIO" environment variable will also be inherited by child R processes launched from the main R session.
RStudio does not initialize its R infrastructure until after R profile scripts are run (e.g. ~/.Rprofile), so checking things like .Platform$GUI == "RStudio" or "tools:rstudio" %in% search() or rstudioapi::isAvailable() won't give what you expect in that context.
On a Mac only the Sys.getenv answer works
platform x86_64-apple-darwin10.8.0
version.string R version 3.1.0 (2014-04-10)
Sys.getenv("RSTUDIO")=="1"
[1] TRUE
RStudio.version()
Error: could not find function "RStudio.version"
any(grepl("RStudio", .libPaths()))
[1] FALSE
.libPaths()
[1] "/Library/Frameworks/R.framework/Versions/3.1/Resources/library"

Elegant way to check for missing packages and install them?

I seem to be sharing a lot of code with coauthors these days. Many of them are novice/intermediate R users and don't realize that they have to install packages they don't already have.
Is there an elegant way to call installed.packages(), compare that to the ones I am loading and install if missing?
Yes. If you have your list of packages, compare it to the output from installed.packages()[,"Package"] and install the missing packages. Something like this:
list.of.packages <- c("ggplot2", "Rcpp")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)
Otherwise:
If you put your code in a package and make them dependencies, then they will automatically be installed when you install your package.
Dason K. and I have the pacman package that can do this nicely. The function p_load in the package does this. The first line is just to ensure that pacman is installed.
if (!require("pacman")) install.packages("pacman")
pacman::p_load(package1, package2, package_n)
You can just use the return value of require:
if(!require(somepackage)){
install.packages("somepackage")
library(somepackage)
}
I use library after the install because it will throw an exception if the install wasn't successful or the package can't be loaded for some other reason. You make this more robust and reuseable:
dynamic_require <- function(package){
if(eval(parse(text=paste("require(",package,")")))) return(TRUE)
install.packages(package)
return(eval(parse(text=paste("require(",package,")"))))
}
The downside to this method is that you have to pass the package name in quotes, which you don't do for the real require.
A lot of the answers above (and on duplicates of this question) rely on installed.packages which is bad form. From the documentation:
This can be slow when thousands of packages are installed, so do not use this to find out if a named package is installed (use system.file or find.package) nor to find out if a package is usable (call require and check the return value) nor to find details of a small number of packages (use packageDescription). It needs to read several files per installed package, which will be slow on Windows and on some network-mounted file systems.
So, a better approach is to attempt to load the package using require and and install if loading fails (require will return FALSE if it isn't found). I prefer this implementation:
using<-function(...) {
libs<-unlist(list(...))
req<-unlist(lapply(libs,require,character.only=TRUE))
need<-libs[req==FALSE]
if(length(need)>0){
install.packages(need)
lapply(need,require,character.only=TRUE)
}
}
which can be used like this:
using("RCurl","ggplot2","jsonlite","magrittr")
This way it loads all the packages, then goes back and installs all the missing packages (which if you want, is a handy place to insert a prompt to ask if the user wants to install packages). Instead of calling install.packages separately for each package it passes the whole vector of uninstalled packages just once.
Here's the same function but with a windows dialog that asks if the user wants to install the missing packages
using<-function(...) {
libs<-unlist(list(...))
req<-unlist(lapply(libs,require,character.only=TRUE))
need<-libs[req==FALSE]
n<-length(need)
if(n>0){
libsmsg<-if(n>2) paste(paste(need[1:(n-1)],collapse=", "),",",sep="") else need[1]
print(libsmsg)
if(n>1){
libsmsg<-paste(libsmsg," and ", need[n],sep="")
}
libsmsg<-paste("The following packages could not be found: ",libsmsg,"\n\r\n\rInstall missing packages?",collapse="")
if(winDialog(type = c("yesno"), libsmsg)=="YES"){
install.packages(need)
lapply(need,require,character.only=TRUE)
}
}
}
if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')
"ggplot2" is the package. It checks to see if the package is installed, if it is not it installs it. It then loads the package regardless of which branch it took.
TL;DR you can use find.package() for this.
Almost all the answers here rely on either (1) require() or (2) installed.packages() to check if a given package is already installed or not.
I'm adding an answer because these are unsatisfactory for a lightweight approach to answering this question.
require has the side effect of loading the package's namespace, which may not always be desirable
installed.packages is a bazooka to light a candle -- it will check the universe of installed packages first, then we check if our one (or few) package(s) are "in stock" at this library. No need to build a haystack just to find a needle.
This answer was also inspired by #ArtemKlevtsov's great answer in a similar spirit on a duplicated version of this question. He noted that system.file(package=x) can have the desired affect of returning '' if the package isn't installed, and something with nchar > 1 otherwise.
If we look under the hood of how system.file accomplishes this, we can see it uses a different base function, find.package, which we could use directly:
# a package that exists
find.package('data.table', quiet=TRUE)
# [1] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/data.table"
# a package that does not
find.package('InstantaneousWorldPeace', quiet=TRUE)
# character(0)
We can also look under the hood at find.package to see how it works, but this is mainly an instructive exercise -- the only ways to slim down the function that I see would be to skip some robustness checks. But the basic idea is: look in .libPaths() -- any installed package pkg will have a DESCRIPTION file at file.path(.libPaths(), pkg), so a quick-and-dirty check is file.exists(file.path(.libPaths(), pkg, 'DESCRIPTION').
This solution will take a character vector of package names and attempt to load them, or install them if loading fails. It relies on the return behaviour of require to do this because...
require returns (invisibly) a logical indicating whether the required package is available
Therefore we can simply see if we were able to load the required package and if not, install it with dependencies. So given a character vector of packages you wish to load...
foo <- function(x){
for( i in x ){
# require returns TRUE invisibly if it was able to load package
if( ! require( i , character.only = TRUE ) ){
# If package was not able to be loaded then re-install
install.packages( i , dependencies = TRUE )
# Load package after installing
require( i , character.only = TRUE )
}
}
}
# Then try/install packages...
foo( c("ggplot2" , "reshape2" , "data.table" ) )
Although the answer of Shane is really good, for one of my project I needed to remove the ouput messages, warnings and install packages automagically. I have finally managed to get this script:
InstalledPackage <- function(package)
{
available <- suppressMessages(suppressWarnings(sapply(package, require, quietly = TRUE, character.only = TRUE, warn.conflicts = FALSE)))
missing <- package[!available]
if (length(missing) > 0) return(FALSE)
return(TRUE)
}
CRANChoosen <- function()
{
return(getOption("repos")["CRAN"] != "#CRAN#")
}
UsePackage <- function(package, defaultCRANmirror = "http://cran.at.r-project.org")
{
if(!InstalledPackage(package))
{
if(!CRANChoosen())
{
chooseCRANmirror()
if(!CRANChoosen())
{
options(repos = c(CRAN = defaultCRANmirror))
}
}
suppressMessages(suppressWarnings(install.packages(package)))
if(!InstalledPackage(package)) return(FALSE)
}
return(TRUE)
}
Use:
libraries <- c("ReadImages", "ggplot2")
for(library in libraries)
{
if(!UsePackage(library))
{
stop("Error!", library)
}
}
# List of packages for session
.packages = c("ggplot2", "plyr", "rms")
# Install CRAN packages (if not already installed)
.inst <- .packages %in% installed.packages()
if(length(.packages[!.inst]) > 0) install.packages(.packages[!.inst])
# Load packages into session
lapply(.packages, require, character.only=TRUE)
Use packrat so that the shared libraries are exactly the same and not changing other's environment.
In terms of elegance and best practice I think you're fundamentally going about it the wrong way. The package packrat was designed for these issues. It is developed by RStudio by Hadley Wickham. Instead of them having to install dependencies and possibly mess up someone's environment system, packrat uses its own directory and installs all the dependencies for your programs in there and doesn't touch someone's environment.
Packrat is a dependency management system for R.
R package dependencies can be frustrating. Have you ever had to use trial-and-error to figure out what R packages you need to install to make someone else’s code work–and then been left with those packages globally installed forever, because now you’re not sure whether you need them? Have you ever updated a package to get code in one of your projects to work, only to find that the updated package makes code in another project stop working?
We built packrat to solve these problems. Use packrat to make your R projects more:
Isolated: Installing a new or updated package for one project won’t break your other projects, and vice versa. That’s because packrat gives each project its own private package library.
Portable: Easily transport your projects from one computer to another, even across different platforms. Packrat makes it easy to install the packages your project depends on.
Reproducible: Packrat records the exact package versions you depend on, and ensures those exact versions are the ones that get installed wherever you go.
https://rstudio.github.io/packrat/
This is the purpose of the rbundler package: to provide a way to control the packages that are installed for a specific project. Right now the package works with the devtools functionality to install packages to your project's directory. The functionality is similar to Ruby's bundler.
If your project is a package (recommended) then all you have to do is load rbundler and bundle the packages. The bundle function will look at your package's DESCRIPTION file to determine which packages to bundle.
library(rbundler)
bundle('.', repos="http://cran.us.r-project.org")
Now the packages will be installed in the .Rbundle directory.
If your project isn't a package, then you can fake it by creating a DESCRIPTION file in your project's root directory with a Depends field that lists the packages that you want installed (with optional version information):
Depends: ggplot2 (>= 0.9.2), arm, glmnet
Here's the github repo for the project if you're interested in contributing: rbundler.
You can simply use the setdiff function to get the packages that aren't installed and then install them. In the sample below, we check if the ggplot2 and Rcpp packages are installed before installing them.
unavailable <- setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages()))
install.packages(unavailable)
In one line, the above can be written as:
install.packages(setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages())))
The current version of RStudio (>=1.2) includes a feature to detect missing packages in library() and require() calls, and prompts the user to install them:
Detect missing R packages
Many R scripts open with calls to library() and require() to load the packages they need in order to execute. If you open an R script that references packages that you don’t have installed, RStudio will now offer to install all the needed packages in a single click. No more typing install.packages() repeatedly until the errors go away!
https://blog.rstudio.com/2018/11/19/rstudio-1-2-preview-the-little-things/
This seems to address the original concern of OP particularly well:
Many of them are novice/intermediate R users and don't realize that they have to install packages they don't already have.
Sure.
You need to compare 'installed packages' with 'desired packages'. That's very close to what I do with CRANberries as I need to compare 'stored known packages' with 'currently known packages' to determine new and/or updated packages.
So do something like
AP <- available.packages(contrib.url(repos[i,"url"])) # available t repos[i]
to get all known packages, simular call for currently installed packages and compare that to a given set of target packages.
The following simple function works like a charm:
usePackage<-function(p){
# load a package if installed, else load after installation.
# Args:
# p: package name in quotes
if (!is.element(p, installed.packages()[,1])){
print(paste('Package:',p,'Not found, Installing Now...'))
install.packages(p, dep = TRUE)}
print(paste('Loading Package :',p))
require(p, character.only = TRUE)
}
(not mine, found this on the web some time back and had been using it since then. not sure of the original source)
I use following function to install package if require("<package>") exits with package not found error. It will query both - CRAN and Bioconductor repositories for missing package.
Adapted from the original work by Joshua Wiley,
http://r.789695.n4.nabble.com/Install-package-automatically-if-not-there-td2267532.html
install.packages.auto <- function(x) {
x <- as.character(substitute(x))
if(isTRUE(x %in% .packages(all.available=TRUE))) {
eval(parse(text = sprintf("require(\"%s\")", x)))
} else {
#update.packages(ask= FALSE) #update installed packages.
eval(parse(text = sprintf("install.packages(\"%s\", dependencies = TRUE)", x)))
}
if(isTRUE(x %in% .packages(all.available=TRUE))) {
eval(parse(text = sprintf("require(\"%s\")", x)))
} else {
source("http://bioconductor.org/biocLite.R")
#biocLite(character(), ask=FALSE) #update installed packages.
eval(parse(text = sprintf("biocLite(\"%s\")", x)))
eval(parse(text = sprintf("require(\"%s\")", x)))
}
}
Example:
install.packages.auto(qvalue) # from bioconductor
install.packages.auto(rNMF) # from CRAN
PS: update.packages(ask = FALSE) & biocLite(character(), ask=FALSE) will update all installed packages on the system. This can take a long time and consider it as a full R upgrade which may not be warranted all the time!
Today, I stumbled on two handy function provided by the rlang package, namely, is_installed() and check_installed().
From the help page (emphasis added):
These functions check that packages are installed with minimal side effects. If installed, the packages will be loaded but not attached.
is_installed() doesn't interact with the user. It simply returns TRUE or FALSE depending on whether the packages are installed.
In interactive sessions, check_installed() asks the user whether to install missing packages. If the user accepts, the packages are installed [...]. If the session is non interactive or if the user chooses not to install the packages, the current evaluation is aborted.
interactive()
#> [1] FALSE
rlang::is_installed(c("dplyr"))
#> [1] TRUE
rlang::is_installed(c("foobarbaz"))
#> [1] FALSE
rlang::check_installed(c("dplyr"))
rlang::check_installed(c("foobarbaz"))
#> Error:
#> ! The package `foobarbaz` is required.
Created on 2022-03-25 by the reprex package (v2.0.1)
I have implemented the function to install and load required R packages silently. Hope might help. Here is the code:
# Function to Install and Load R Packages
Install_And_Load <- function(Required_Packages)
{
Remaining_Packages <- Required_Packages[!(Required_Packages %in% installed.packages()[,"Package"])];
if(length(Remaining_Packages))
{
install.packages(Remaining_Packages);
}
for(package_name in Required_Packages)
{
library(package_name,character.only=TRUE,quietly=TRUE);
}
}
# Specify the list of required packages to be installed and load
Required_Packages=c("ggplot2", "Rcpp");
# Call the Function
Install_And_Load(Required_Packages);
Quite basic one.
pkgs = c("pacman","data.table")
if(length(new.pkgs <- setdiff(pkgs, rownames(installed.packages())))) install.packages(new.pkgs)
Thought I'd contribute the one I use:
testin <- function(package){if (!package %in% installed.packages())
install.packages(package)}
testin("packagename")
Regarding your main objective " to install libraries they don't already have. " and regardless of using " instllaed.packages() ". The following function mask the original function of require. It tries to load and check the named package "x" , if it's not installed, install it directly including dependencies; and lastly load it normaly. you rename the function name from 'require' to 'library' to maintain integrity . The only limitation is packages names should be quoted.
require <- function(x) {
if (!base::require(x, character.only = TRUE)) {
install.packages(x, dep = TRUE) ;
base::require(x, character.only = TRUE)
}
}
So you can load and installed package the old fashion way of R.
require ("ggplot2")
require ("Rcpp")
48 lapply_install_and_load <- function (package1, ...)
49 {
50 #
51 # convert arguments to vector
52 #
53 packages <- c(package1, ...)
54 #
55 # check if loaded and installed
56 #
57 loaded <- packages %in% (.packages())
58 names(loaded) <- packages
59 #
60 installed <- packages %in% rownames(installed.packages())
61 names(installed) <- packages
62 #
63 # start loop to determine if each package is installed
64 #
65 load_it <- function (p, loaded, installed)
66 {
67 if (loaded[p])
68 {
69 print(paste(p, "loaded"))
70 }
71 else
72 {
73 print(paste(p, "not loaded"))
74 if (installed[p])
75 {
76 print(paste(p, "installed"))
77 do.call("library", list(p))
78 }
79 else
80 {
81 print(paste(p, "not installed"))
82 install.packages(p)
83 do.call("library", list(p))
84 }
85 }
86 }
87 #
88 lapply(packages, load_it, loaded, installed)
89 }
source("https://bioconductor.org/biocLite.R")
if (!require("ggsci")) biocLite("ggsci")
Using lapply family and anonymous function approach you may:
Try to attach all listed packages.
Install missing only (using || lazy evaluation).
Attempt to attach again those were missing in step 1 and installed in step 2.
Print each package final load status (TRUE / FALSE).
req <- substitute(require(x, character.only = TRUE))
lbs <- c("plyr", "psych", "tm")
sapply(lbs, function(x) eval(req) || {install.packages(x); eval(req)})
plyr psych tm
TRUE TRUE TRUE
I use the following which will check if package is installed and if dependencies are updated, then loads the package.
p<-c('ggplot2','Rcpp')
install_package<-function(pack)
{if(!(pack %in% row.names(installed.packages())))
{
update.packages(ask=F)
install.packages(pack,dependencies=T)
}
require(pack,character.only=TRUE)
}
for(pack in p) {install_package(pack)}
completeFun <- function(data, desiredCols) {
completeVec <- complete.cases(data[, desiredCols])
return(data[completeVec, ])
}
Here's my code for it:
packages <- c("dplyr", "gridBase", "gridExtra")
package_loader <- function(x){
for (i in 1:length(x)){
if (!identical((x[i], installed.packages()[x[i],1])){
install.packages(x[i], dep = TRUE)
} else {
require(x[i], character.only = TRUE)
}
}
}
package_loader(packages)
library <- function(x){
x = toString(substitute(x))
if(!require(x,character.only=TRUE)){
install.packages(x)
base::library(x,character.only=TRUE)
}}
This works with unquoted package names and is fairly elegant (cf. GeoObserver's answer)
In my case, I wanted a one liner that I could run from the commandline (actually via a Makefile). Here is an example installing "VGAM" and "feather" if they are not already installed:
R -e 'for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")'
From within R it would just be:
for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")
There is nothing here beyond the previous solutions except that:
I keep it to a single line
I hard code the repos parameter (to avoid any popups asking about the mirror to use)
I don't bother to define a function to be used elsewhere
Also note the important character.only=TRUE (without it, the require would try to load the package p).
Let me share a bit of madness:
c("ggplot2","ggsci", "hrbrthemes", "gghighlight", "dplyr") %>% # What will you need to load for this script?
(function (x) ifelse(t =!(x %in% installed.packages()),
install.packages(x[t]),
lapply(x, require)))
There is a new-ish package (I am a codeveloper), Require, that is intended to be part of a reproducible workflow, meaning the function produces the same output the first time it is run or subsequent times, i.e., the end-state is the same regardless of starting state. The following installs any missing packages (I include require = FALSE to strictly address the original question... normally I leave this on the default because I will generally want them loaded to the search path).
These two lines are at the top of every script I write (adjusting the package selection as necessary), allowing the script to be used by anybody in any condition (including any or all dependencies missing).
if (!require("Require")) install.packages("Require")
Require::Require(c("ggplot2", "Rcpp"), require = FALSE)
You can thus use this in your script or pass it anyone.

Resources