不可重复的R包可用性检查

时间:2017-07-17 13:33:55

标签: r

在检查包矢量是否需要安装时,我遇到了一个有趣的错误。请求和卸载lme4命名空间会在第二次执行时出错,但仅在按特定顺序检查某些其他包时才会出错。

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)

我在isInstalled做错了吗?

这可能与car的依赖结构有关。简化版: 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

1 个答案:

答案 0 :(得分:7)

R的设计并不是为了允许随意加载和卸载软件包。您可以尝试这样做,但不能保证成功(尽管经常这样做)。

来自?detach

  

如果一个包有一个命名空间,那么在默认情况下卸载它不会卸载命名空间(甚至可能不会使用unload = TRUE),并且分离通常不会卸载任何动态加载的编译代码(DLL)。此外,不会删除命名空间中注册的S3方法。如果在加载了命名空间的包上使用库,则会附加已加载的命名空间的导出。因此,分离和重新附加包可能不会刷新包的一些或所有组件,并且是不可取的。

来自?devtools::unload

  

此函数尝试干净地卸载程序包,包括卸载其名称空间,删除S4类定义以及卸载任何加载的DLL。不幸的是,S4类并没有真正被设计为干净地卸载,因此我们必须手动修改类依赖图以使其工作 - 这适用于我们已经测试但可能有其他情况的情况。同样,自动DLL卸载最好针对简单场景进行测试(特别是使用useDynLib(pkgname),并且在其他情况下可能会失败。如果遇到失败,请在http://github.com/hadley/devtools/issues提交错误报告。