Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

non-reproducible R package availability check

Tags:

r

I came across an interesting error when checking a vector of packages whether they need to be installed. Requiring and unloading the lme4 namespace gives an error the second time it is performed, but only when some other packages are checked in a certain order.

isInstalled <- function(package)    # is a package installed and usable?
  {
  loaded <- package %in% .packages()
  out <- requireNamespace(package, quietly=F)
  if(!loaded) try(unloadNamespace(package), silent=F)
  out
  }

isInstalled("car")      # All return TRUE
isInstalled("nnet")
isInstalled("pbkrtest")
isInstalled("lme4")
isInstalled("nloptr")
isInstalled("lme4")     # FALSE (only after commands above)
# no such symbol NLoptR_Optimize in package C:/__Rlibrary/nloptr/libs/x64/nloptr.dll
library(nloptr) # now fails, too

# Problem solved if nnet is checked before car (but not again after car)

Am I doing something wrong in isInstalled?

This might be related to the dependency structure of car. Simplified version: simplified car dependency graph

#install.packages(c("miniCRAN","igraph"))
d <- miniCRAN::makeDepGraph(c("car", "nnet", "pbkrtest", "lme4","nloptr"), suggests=FALSE)
plot(d) # for full dependency graph
like image 619
Berry Boessenkool Avatar asked Jul 17 '17 13:07

Berry Boessenkool


1 Answers

R isn't really designed to allow packages to be loaded and unloaded at will. You can attempt to do so, but it isn't guaranteed to succeed (although it often does).

From ?detach:

If a package has a namespace, detaching it does not by default unload the namespace (and may not even with unload = TRUE), and detaching will not in general unload any dynamically loaded compiled code (DLLs). Further, registered S3 methods from the namespace will not be removed. If you use library on a package whose namespace is loaded, it attaches the exports of the already loaded namespace. So detaching and re-attaching a package may not refresh some or all components of the package, and is inadvisable.

From ?devtools::unload:

This function attempts to cleanly unload a package, including unloading its namespace, deleting S4 class definitions and unloading any loaded DLLs. Unfortunately S4 classes are not really designed to be cleanly unloaded, and so we have to manually modify the class dependency graph in order for it to work - this works on the cases for which we have tested but there may be others. Similarly, automated DLL unloading is best tested for simple scenarios (particularly with useDynLib(pkgname) and may fail in other cases. If you do encounter a failure, please file a bug report at http://github.com/hadley/devtools/issues.

like image 157
Hong Ooi Avatar answered Oct 14 '22 18:10

Hong Ooi