如何在[R]中确定命名空间导入顺序

Tar*_*rek 6 r ggplot2

我需要清理一个R实例,使其恢复到启动时的处女状态.到目前为止,我正在做的是:

在启动时,记录加载的包和名称空间

original_packages <- grep('^package:', search(), value = TRUE)
original_namespaces <- loadedNamespaces()
Run Code Online (Sandbox Code Playgroud)

当我需要刷新实例时,分离每个在启动时不存在的已加载包:

for (pkg in grep('^package:', search(), value = TRUE)) {
    if (! pkg %in% original_packages){
        detach(pkg, unload=TRUE, force=TRUE, character.only=TRUE)
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,如果我装一个包和一帮导入的命名空间,如GGPLOT2的,这些空间中保持加载,我必须卸载它们进口的顺序,从高层次的下降.只是盲目地卸载它们不起作用,因为我得到"命名空间'x'由'y'导入,'z'因此无法卸载"错误.

这是可重复的例子:

original_packages <- grep('^package:', search(), value = TRUE)
original_namespaces <- loadedNamespaces()

library(ggplot2)
library(plyr)

loadedNamespaces()

for (pkg in grep('^package:', search(), value = TRUE)) {
    if (! pkg %in% original_packages){
        detach(pkg, unload=TRUE, force=TRUE, character.only=TRUE)
    }
}

for (ns in loadedNamespaces()) {
    if (! ns %in% original_namespaces){
        unloadNamespace(ns)
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法找出命名空间导入层次结构?如果是这样,那么我应该能够正确地订购最后一个循环......

sgi*_*ibb 0

正如 @Josh O'Brien 提到的,不可能通过分离或卸载命名空间来获得干净的环境。

但要回答您的问题,这里有一种简单的方法,可以使用以下命令按正确的顺序卸载所有名称空间tools:::dependsOnPkgs

## params: originalNamespaces is a list of namespaces you want to keep
cleanNamespaces <- function(originalNamespaces) {

    ## which namespaces should be removed?
    ns <- setdiff(loadedNamespaces(), originalNamespaces)

    ## get dependency list
    dep <- unlist(lapply(ns, tools:::dependsOnPkgs))

    ## append namespaces to guarantee to fetch namespaces with 
    ## no reverse dependencies
    ns <- c(dep, ns)

    ## get namespace names in correct order to unload without errors
    ns <- names(sort(table(ns), decreasing=TRUE))

    ## only unload namespaces which are attached
    ns <- ns[ns %in% loadedNamespaces()]

    ## unload namespaces
    invisible(sapply(ns, unloadNamespace))
}
Run Code Online (Sandbox Code Playgroud)