在 R 中卸载/分离所有加载的命名空间和附加包

Was*_*amo 5 namespaces r package

我遇到了全局范围被附加包 ( sessionInfo()$otherPkgs) 和命名空间 (loadedNamespaces() )。所以我想在我的脚本开始时清除它们。

在这个线程中解决了一半的问题。这个问题的主要区别在于我想卸载命名空间,而不仅仅是分离包。pacman 也很有趣,但似乎也不起作用。

library(dbplyr)
names(sessionInfo()$otherPkgs)
lapply(paste("package:", names(sessionInfo()$otherPkgs), sep=""), 
   detach, character.only = TRUE, unload = TRUE)
# `dbplyr` is detached
names(sessionInfo()$otherPkgs)
Run Code Online (Sandbox Code Playgroud)

但是卸载已加载命名空间的类似方法似乎更具挑战性,因为必须首先卸载依赖于其他名称的包。

这是我的尝试:

# Recursive unload which checks for reverse dependencies (children) along the way
# and unloads them first
myunload <- function(pkg) {
    # Get child (reverse-dependent) packages that have loaded namespaces
    child_pkgs <- unlist(tools::dependsOnPkgs(pkg, which = c("Depends", "Imports"), reverse = T))
    child_pkgs <- child_pkgs[which(child_pkgs %in% loadedNamespaces())]
    # Recursively unload child packages
    lapply(child_pkgs, myunload)
    unloadNamespace(pkg)
}
# Apply over all our loaded namespaces
lapply(loadedNamespaces(), myunload)
Run Code Online (Sandbox Code Playgroud)

测试它:

lapply(loadedNamespaces(), myunload)
Run Code Online (Sandbox Code Playgroud)

unloadNamespace(pkg) 中的错误:命名空间“grDevices”由“grid”、“graphics”、“stats”导入,因此无法卸载

看起来它正在尝试卸载基础包,这不是我的意图。我不确定如何指定无基础包。

我想使用,detach(..., unload=T, character.only=T, force=T)但这失败了,如文档中所述:

...如果命名空间由另一个命名空间导入或卸载为 FALSE,则不会发生卸载。

是否有一种更简单或有效的方法来卸载所有命名空间,包括那些可能被其他人导入的命名空间?如果命名空间由另一个命名空间导入或卸载为 FALSE,则不会发生卸载。

jay*_*.sf 0

我们可以使用一个while循环来完成此操作,直到卸载除基本包、自定义包和自定义包try之外的所有不需要的东西。bpk"rstudioapi"exc

更具体地说,它会跳过由于每次迭代中的依赖关系而无法卸载的命名空间,确保它们最后被卸载。

unload_pkgs <- \(exc=NULL) {
  bpk <- c("compiler", "graphics", "tools", "utils", "grDevices", "stats", 
           "datasets", "methods", "base", "rstudioapi") |> c(exc)
  while (length(setdiff(loadedNamespaces(), bpk)) > 0) {
    lapply(setdiff(loadedNamespaces(), bpk), \(x) {
      try(unloadNamespace(x), silent=TRUE)
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

用法

## load some packages
library(ggplot2)
library(Rcpp)
library(MASS)

loadedNamespaces()
# [1] "Rcpp"       "assertthat" "utf8"       "R6"        
# [5] "ggplot2"    "pillar"     "utils"      "rlang"     
# [9] "rstudioapi" "munsell"    "compiler"   "pkgconfig" 
# [13] "stats"      "tidyselect" "tibble"     "grDevices" 
# [17] "fansi"      "withr"      "dplyr"      "MASS"      
# [21] "grid"       "gtable"     "lifecycle"  "DBI"       
# [25] "magrittr"   "datasets"   "scales"     "cli"       
# [29] "graphics"   "vctrs"      "generics"   "base"      
# [33] "tools"      "glue"       "colorspace" "methods"   

unload_pkgs(exc=c('Rcpp', 'MASS'))  ## exclude 'Rcpp' and 'MASS' from unload
loadedNamespaces()
# [1] "Rcpp"       "grDevices"  "MASS"       "datasets"  
# [5] "utils"      "rstudioapi" "graphics"   "base"      
# [9] "tools"      "compiler"   "stats"      "methods" 

unload_pkgs()  ## unload ALL non-base
loadedNamespaces()
# [1] "grDevices"  "datasets"   "utils"      "rstudioapi"
# [5] "graphics"   "base"       "tools"      "compiler"  
# [9] "stats"      "methods" 
Run Code Online (Sandbox Code Playgroud)