R function `require` does not work as expected in `sapply` - r

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:
'not_available' is not installed :)
'testthat' is installed.
# 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.

Related

Trying to install the Performance Analytics in R

I'm trying to install the package 'Performance Analysis' in the R script below:
tryCatch(
expr = {
#library('PerformanceAnalytics', verbose = FALSE, quietly = TRUE)
library("PerformanceAnalytics",lib.loc=.libPaths(),verbose = FALSE, quietly = TRUE)
},
error = function(e){
print(e)
install.packages('PerformanceAnalytics', repos='https://cran.rstudio.com', verbose = FALSE)
#library('PerformanceAnalytics', verbose = FALSE, quietly = TRUE)
library("PerformanceAnalytics",lib.loc=.libPaths(),verbose = FALSE, quietly = TRUE)
}
)
But I'm having the following error message (Version 1.2.1335 of R Studio). Does anyone know if I've made a mistake somewhere?
Thanks
unable to access index for repository https://cran.rstudio.com/bin/windows/contrib/3.1
Installing package into ‘C:/Users/xxxxx/Documents/R/win-library/3.1’
(as ‘lib’ is unspecified)
Warning in install.packages :
unable to access index for repository https://cran.rstudio.com/bin/windows/contrib/3.1
Warning in install.packages :
package ‘PerformanceAnalytics’ is not available (as a binary package for R version 3.1.3)
Error in library("PerformanceAnalytics", lib.loc = .libPaths(), verbose = FALSE, :
there is no package called ‘PerformanceAnalytics’

Loop and If statement to check and load packages

Why wont require take a vector of packages? Also is there a way to split pkg for both install.package and BiocManager? Thus, if packages fails to install with install.package, check with BiocManager?
Error:
[1] "stringr"
Loading required package: i
Error in print.default("trying to install", i) :
invalid printing digits -2147483648
In addition: Warning messages:
1: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
there is no package called ‘i’
2: In print.default("trying to install", i) : NAs introduced by coercion
pkg <- c("stringr", "openxlsx")
for (i in pkg){
print(i)
if(require(i)){
print(i, "is loaded correctly")
} else{
print("trying to install", i)
install.packages(i)
if(require(i)){
print(i, "installed and loaded")
} else{
stop("could not install", i)
}
}
}
There are were at least 3 errors in that for loop. First, a missing argument to the first require,
... then failing to set the character.only argument for requireto TRUE so that i can get evaluated rather than taken as a package name, (see ?require Arguments section)
... and finally, failing to join the desired character values in the print calls with paste. (See ?print.default's Argument section. The print function only prints its first argument. Its second argument is the number of digits, as stated by the console error message.)
pkg <- c("stringr", "openxlsx")
for (i in pkg){
print(i)
if(require(i, character.only=TRUE)){
print(paste(i, "is loaded correctly"))
} else{
print(paste("trying to install", i))
install.packages(i)
if(require(i, character.only=TRUE)){
print(paste(i, "installed and loaded"))
} else{
stop(paste("could not install", i))
}
}
}
I did get : "Warning message:
In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
there is no package called ‘openxlsx’" after the first run of that loop which I do not understand (since the message [1] "openxlsx installed and loaded" was printed, and the package did get installed and could be loaded. I'm guessing it had something to do with these activities being done within a function and there was some mismatch of environments??? When I removed pkg:openxlsx and re-ran my code I do not get the warning message.

Using R alone, is it possible to have packages as a variable in a function?

I'm just testing loading different packages, and I wrote a function that I thought would let me add and remove packages as needed. For example, if I wanted to load spatstat:
packagedelivery<-function(fry,leela){
if(fry == TRUE){
library(leela)
} else{
detach(leela,unload=TRUE)
}
}
packagedelivery(TRUE,"spatstat")
R kicks up an error, stating:
Error in library(leela) : there is no package called ‘leela’
What steps am I missing here?
Many thanks.
There's a character.only= argument in library(). To get detach() to work properly you simply need to add what sort of thing is to detach, in this case 'package:'
packagedelivery1 <- function(fry, leela) {
if (fry) {
library(leela, character.only=TRUE)
} else {
detach(sprintf('package:%s', leela), unload=TRUE, character.only=TRUE)
}
}
packagedelivery1(TRUE, "matrixStats")
colSds(matrix(rnorm(9), 3, 3))
# [1] 1.6706355 0.5352099 1.4046043
packagedelivery1(FALSE, "matrixStats") ## first unload
colSds(matrix(rnorm(9), 3, 3))
# Error in colSds(matrix(rnorm(9), 3, 3)) :
# could not find function "colSds"
packagedelivery2(FALSE, "lfe") ## second unload (package not loaded)
# Error in detach(sprintf("package:%s", leela), unload = T, character.only = T) :
# invalid 'name' argument
packagedelivery1(TRUE, "fooPackage")
# Error in library(leela, character.only = TRUE) :
# there is no package called ‘fooPackage’
Works as expected. And throws errors when package is not or no longer available.
You also could create a different function that warns instead of throwing errors, using require() and unloadNamespace():
packagedelivery2 <- function(fry, leela) {
srh <- sprintf("package:%s", leela) %in% search()
if (fry) {
if (srh) {
message(sprintf("Package called '%s' already loaded", leela))
} else {
require(leela, character.only=TRUE)
}
} else {
if (!srh) {
message(sprintf("There was no package called '%s'", leela))
}
unloadNamespace(leela)
}
}
packagedelivery2(TRUE, "matrixStats")
colSds(matrix(rnorm(9), 3, 3))
# [1] 0.4954492 1.1789422 1.1264789
packagedelivery2(FALSE, "matrixStats") ## first unload
colSds(matrix(rnorm(9), 3, 3))
# Error in colSds(matrix(rnorm(9), 3, 3)) :
# could not find function "colSds"
packagedelivery2(FALSE, "matrixStats") ## second unload (package not loaded)
# There was no package called 'matrixStats'
packagedelivery2(TRUE, "fooPackage")
# Loading required package: fooPackage
# Warning message:
# In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
# there is no package called ‘fooPackage’
Note, that require() has an invisible output that you may use to install a missing package, just look into this famous answer.

Elegant way to load a string list of packages in R

Hi I've written the following code:
################# Loadin Require Libraries #################
required.packages <- c('caret','readxl')
for (pkg in required.packages){
if(!require(pkg, character.only = T)){
install.packages(pkg,
character.only = T,
dependencies = T)
library(pkg, character.only = T)
}else{
library(pkg, character.only = T)
}
}
The code shall be ran on a computer of a peer, so to take care of might missing libraries I thought I iterate threw a string list, to check if the package is installed if yes -> load if no -> install and load then. However when a package is not available R still puts out a warning message:
Warning message:
In library(package, lib.loc = lib.loc, character.only = TRUE,
logical.return = TRUE, : es gibt kein Paket namens ‘readxl’
My question: is there a better way to check / install a bunch of libraries in R? Should I care about the warning? If it is not important is there a way to surpress this warning getting printed?
Edit: Final solution Thanks to the correct answer provided by #akrun:
################# Loadin Require Libraries #################
lib <- .libPaths()[1]
required.packages <- c('caret','readxl')
i1 <- !(required.packages %in% row.names(installed.packages()))
if(any(i1)) {
install.packages(required.packages[i1], dependencies = TRUE, lib = lib)
}
lapply(required.packages, require, character.only = TRUE)
Update 2021 - Pacman
I found the pacman - package really helpful for exactly this purpose, especially the p_load function. It checks if the package is installed and otherwise tries to install the missing package.
This function is a wrapper for library and require. It checks to see
if a package is installed, if not it attempts to install the package
from CRAN and/or any other repository in the pacman repository list.
So nowadays I start all my scripts that need to be 'portable' with the following lines:
require(pacman)
# Load / Install Required Packages
p_load(dplyr, tidyr, gridExtra, psych)
In this case to load / install dplyr, tidyr, gridExtra & psych
Also nice in this package (if you want to clean up the environment) p_unload
# Unload All packages
p_unload()
Here is one option
Pkgs <- c('caret','readxl')
lib <- .libPaths()[1]
i1 <- !(Pkgs %in% row.names(installed.packages()))
if(any(i1)) {
install.packages(Pkgs[i1], dependencies = TRUE, lib = lib)
}

Problems installing R packages

I'm setting up a new laptop running Gentoo and wish to install R (as I do on all of my computers!).
However, I've hit a bit of a problem when it comes to installing packages.
I first tried to:
> install.packages(c("ggplot2", "plyr", "reshape2"))
And it duly downloaded all of the packages and its dependencies. However they didn't install reporting.
Error in library(data.table) : there is no package called ‘data.table’
Calls: .First -> library
Execution halted
Error in library(data.table) : there is no package called ‘data.table’
Calls: .First -> library
Execution halted
Error in library(data.table) : there is no package called ‘data.table’
Calls: .First -> library
Execution halted
Error in library(data.table) : there is no package called ‘data.table’
Calls: .First -> library
Execution halted
Error in library(data.table) : there is no package called ‘data.table’
Calls: .First -> library
Execution halted
Error in library(data.table) : there is no package called ‘data.table’
Calls: .First -> library
Execution halted
Error in library(data.table) : there is no package called ‘data.table’
Calls: .First -> library
Execution halted
Error in library(data.table) : there is no package called ‘data.table’
Calls: .First -> library
Not a problem I'll just install the data.table package, unfortunately...
> install.packages("data.table")
trying URL 'http://cran.uk.r-project.org/src/contrib/data.table_1.8.2.tar.gz'
Content type 'application/x-gzip' length 818198 bytes (799 Kb)
opened URL
==================================================
downloaded 799 Kb
Error in library(data.table) : there is no package called ‘data.table’
Calls: .First -> library
Execution halted
The downloaded source packages are in
‘/tmp/RtmpbQtALj/downloaded_packages’
Updating HTML index of packages in '.Library'
Making packages.html ... done
Warning message:
In install.packages("data.table") :
installation of package ‘data.table’ had non-zero exit status
And there is no indication of why installation failed at all, so I've no idea how to go about solving this? A traceback() isn't available either.
GCC is installed and configured as the output of gcc-config shows (and the fact that I can install other software from source no problem).
# gcc-config -l
[1] x86_64-pc-linux-gnu-4.6.3 *
Stumped as to how to go about solving this one. Any thoughts or ideas on how to get more information out of install.packages() welcome.
EDIT : contents of .First as requested....
> .First
function ()
{
library(data.table)
library(foreign)
library(ggplot2)
library(Hmisc)
library(lattice)
library(plyr)
library(rms)
library(xtable)
cat("\nWelcome at", date(), "\n")
}
EDIT 2 : No Rprofile.site but there is /usr/lib64/R/library/base/R/Rprofile which has....
# cat /usr/lib64/R/library/base/R/Rprofile
### This is the system Rprofile file. It is always run on startup.
### Additional commands can be placed in site or user Rprofile files
### (see ?Rprofile).
### Notice that it is a bad idea to use this file as a template for
### personal startup files, since things will be executed twice and in
### the wrong environment (user profiles are run in .GlobalEnv).
.GlobalEnv <- globalenv()
attach(NULL, name = "Autoloads")
.AutoloadEnv <- as.environment(2)
assign(".Autoloaded", NULL, envir = .AutoloadEnv)
T <- TRUE
F <- FALSE
R.version <- structure(R.Version(), class = "simple.list")
version <- R.version # for S compatibility
## for backwards compatibility only
R.version.string <- R.version$version.string
## NOTA BENE: options() for non-base package functionality are in places like
## --------- ../utils/R/zzz.R
options(keep.source = interactive())
options(warn = 0)
# options(repos = c(CRAN="#CRAN#"))
# options(BIOC = "http://www.bioconductor.org")
options(timeout = 60)
options(encoding = "native.enc")
options(show.error.messages = TRUE)
## keep in sync with PrintDefaults() in ../../main/print.c :
options(scipen = 0)
options(max.print = 99999)# max. #{entries} in internal printMatrix()
options(add.smooth = TRUE)# currently only used in 'plot.lm'
options(stringsAsFactors = TRUE)
if(!interactive() && is.null(getOption("showErrorCalls")))
options(showErrorCalls = TRUE)
local({dp <- Sys.getenv("R_DEFAULT_PACKAGES")
if(identical(dp, "")) # marginally faster to do methods last
dp <- c("datasets", "utils", "grDevices", "graphics",
"stats", "methods")
else if(identical(dp, "NULL")) dp <- character(0)
else dp <- strsplit(dp, ",")[[1]]
dp <- sub("[[:blank:]]*([[:alnum:]]+)", "\\1", dp) # strip whitespace
options(defaultPackages = dp)
})
## Expand R_LIBS_* environment variables.
Sys.setenv(R_LIBS_SITE =
.expand_R_libs_env_var(Sys.getenv("R_LIBS_SITE")))
Sys.setenv(R_LIBS_USER =
.expand_R_libs_env_var(Sys.getenv("R_LIBS_USER")))
.First.sys <- function()
{
for(pkg in getOption("defaultPackages")) {
res <- require(pkg, quietly = TRUE, warn.conflicts = FALSE,
character.only = TRUE)
if(!res)
warning(gettextf('package %s in options("defaultPackages") was not found', sQuote(pkg)),
call.=FALSE, domain = NA)
}
}
.OptRequireMethods <- function()
{
if("methods" %in% getOption("defaultPackages")) {
res <- require("methods", quietly = TRUE, warn.conflicts = FALSE,
character.only = TRUE)
if(!res)
warning('package "methods" in options("defaultPackages") was not found', call.=FALSE)
}
}
if(nzchar(Sys.getenv("R_BATCH"))) {
.Last.sys <- function()
{
cat("> proc.time()\n")
print(proc.time())
}
## avoid passing on to spawned R processes
## A system has been reported without Sys.unsetenv, so try this
try(Sys.setenv(R_BATCH=""))
}
###-*- R -*- Unix Specific ----
.Library <- file.path(R.home(), "library")
.Library.site <- Sys.getenv("R_LIBS_SITE")
.Library.site <- if(!nchar(.Library.site)) file.path(R.home(), "site-library") else unlist(strsplit(.Library.site, ":"))
.Library.site <- .Library.site[file.exists(.Library.site)]
invisible(.libPaths(c(unlist(strsplit(Sys.getenv("R_LIBS"), ":")),
unlist(strsplit(Sys.getenv("R_LIBS_USER"), ":")
))))
local({
## we distinguish between R_PAPERSIZE as set by the user and by configure
papersize <- Sys.getenv("R_PAPERSIZE_USER")
if(!nchar(papersize)) {
lcpaper <- Sys.getlocale("LC_PAPER") # might be null: OK as nchar is 0
papersize <- if(nchar(lcpaper))
if(length(grep("(_US|_CA)", lcpaper))) "letter" else "a4"
else Sys.getenv("R_PAPERSIZE")
}
options(papersize = papersize,
printcmd = Sys.getenv("R_PRINTCMD"),
dvipscmd = Sys.getenv("DVIPS", "dvips"),
texi2dvi = Sys.getenv("R_TEXI2DVICMD"),
browser = Sys.getenv("R_BROWSER"),
pager = file.path(R.home(), "bin", "pager"),
pdfviewer = Sys.getenv("R_PDFVIEWER"),
useFancyQuotes = TRUE)
})
## non standard settings for the R.app GUI of the Mac OS X port
if(.Platform$GUI == "AQUA") {
## this is set to let RAqua use both X11 device and X11/TclTk
if (Sys.getenv("DISPLAY") == "")
Sys.setenv("DISPLAY" = ":0")
## this is to allow gfortran compiler to work
Sys.setenv("PATH" = paste(Sys.getenv("PATH"),":/usr/local/bin",sep = ""))
}## end "Aqua"
local({
tests_startup <- Sys.getenv("R_TESTS")
if(nzchar(tests_startup)) source(tests_startup)
})
Looks like data.table is not installed for the user that is running the install.packages command. I think wrapping that .First function in if (interactive()) { } would be a good idea in general. Otherwise, you need to install data.table and any other packages that load at startup since install.packages runs the .Rprofile file when starting
WARNING: You're using a non-UTF8 locale, therefore only ASCII characters will work.
Please read R for Mac OS X FAQ (see Help) section 9 and adjust your system preferences accordingly.
[History restored from /Users/carlosaburto/.Rapp.history]
defaults write org.R-project.R force.LANG en_US.UTF-8
Error: unexpected symbol in "defaults write"
starting httpd help server ... done

Resources