卸载(删除)具有依赖项的R包

时间:2014-10-26 13:13:45

标签: r

我想尝试一些新包装。我安装它,它需要很多依赖,所以它安装了很多其他的包。我试过了,我没有留下深刻印象 - 现在我想卸载包含所有依赖项的包!

有没有办法删除给定的包,包括系统中任何其他包不需要的所有依赖项?

我看了?remove.packages,但没有选择这样做。

4 个答案:

答案 0 :(得分:18)

以下是一些代码,可以删除包及其不需要的依赖项。请注意,它对“不需要的”依赖包的解释是此包依赖的包的集合,但未在任何其他包中使用。这意味着它还默认建议卸载没有反向依赖关系的包。因此,我将其实现为交互式菜单(如update.packages),以便您控制要卸载的内容。

library("tools")

removeDepends <- function(pkg, recursive = FALSE){
    d <- package_dependencies(,installed.packages(), recursive = recursive)
    depends <- if(!is.null(d[[pkg]])) d[[pkg]] else character()
    needed <- unique(unlist(d[!names(d) %in% c(pkg,depends)]))
    toRemove <- depends[!depends %in% needed]
    if(length(toRemove)){
         toRemove <- select.list(c(pkg,sort(toRemove)), multiple = TRUE,
                                 title = "Select packages to remove")
         remove.packages(toRemove)
         return(toRemove)
    } else {
        invisible(character())
    }
}

# Example
install.packages("YplantQMC") # installs an unneeded dependency "LeafAngle"
c("YplantQMC","LeafAngle") %in% installed.packages()[,1]
## [1] TRUE TRUE
removeDepends("YplantQMC")
c("YplantQMC","LeafAngle")  %in% installed.packages()[,1]
## [1] FALSE FALSE

注意:recursive选项可能特别有用。如果包依赖性进一步依赖于其他不需要的包,则设置recursive = TRUE至关重要。如果依赖关系很浅(即依赖关系树中只有一个级别),则可以保留为FALSE(默认值)。

答案 1 :(得分:10)

实际上基础R中有一个函数remove.packages(),但它在utils包中,您需要先加载它:

library(utils)
remove.packages()

我不完全清楚这个功能有多少递归清理。

答案 2 :(得分:5)

base种方法可以解决这个问题,但我会推荐一个包(我知道你正试图摆脱这些)。我推荐这个包有两个原因(1)它解决了你遇到的两个问题&amp; (2)Dason K.和我正在开发这个包(完全披露)。这个包的价值在于函数更容易记住一致的名称。它还做了一些组合操作。请注意,你可以在基础上完成所有这些,但这个问题已经非常本地化,因此我将使用一种工具,使回答更容易。

这个包将:

  1. 允许您删除包和依赖项
  2. 允许您在临时目录而不是主库中安装包
  3. 需要注意的是,您不能100%确定用户先前已安装的软件包依赖项尚未存在。因此,我会谨慎对待此解决方案的每一步,您不会删除重要的内容。此解决方案依赖于2个因素(1)pacman(2)file.info。我们假设在某个(用户定义的)时间阈值内修改的依赖关系确实是不需要的包。请注意这里的词假设。

    我为家里的人们制作了这个可重现性,答案是从CRAN中随机安装一个带有附加依赖项的软件包(这会安装一个你本地没有3个或更多依赖项的软件包;随机使用不会挑出任何一个封装)。

    制作可重复的示例

    library(pacman)
    
    (available <- p_cran())
    (randoms <- setdiff(available,  p_lib()))
    (mypackages <- p_lib())
    
    ndeps <- 1
    while(ndeps < 3) {
    
        package <- sample(randoms, 1)
        deps <- unlist(p_depends(package, character.only=TRUE), use.names=FALSE)
        ndeps <- length(setdiff(deps,  mypackages))
    
    }  
    
    package
    p_install(package, character.only = TRUE)
    

    卸载软件包

    我们会将第一部分的包名称分配给package,或者OP可以使用他们安装的不需要的包,并将其分配给package(我的随机包恰好是package <- "OrdinalLogisticBiplot" )。理想情况下,此删除过程应在干净的R会话中完成,不会加载附加软件包(pacman除外)。

    ## function to grab file info date/time modified
    infograb <- function(x) file.info(file.path(p_path(), x))[["mtime"]]
    
    ## determine the differences in times modified for "package" 
    ## and all other packages in library
    diffs <- as.numeric(infograb(package)) -  sapply(p_lib(), infograb)
    
    ## user defined threshold
    threshold <- 15
    
    ## determine packages just installed within the time frame of the unwanted package 
    (delete_deps <- diffs[diffs < threshold & diffs >= 0])
    
    ## recursively find all packages that could have been installed 
    potential_depends <- unlist(lapply(unlist(p_depends(package, character=TRUE)), 
        p_depends, character=TRUE, recursive=TRUE))
    
    ## delete packages that are both on the lists of (1) installed within time
    ## frame of unwanted package and a dependency of that package
    p_delete(intersect(names(delete_deps), potential_depends), character.only = TRUE)
    

    这种做法有一些很大的假设。

    从一开始就采用更好的方法

    p_temp(package_to_try)
    

    这允许您先尝试一下,而不是让您的本地图书馆变得混乱。

    如果您对pacman不满意,可以使用上述方法将其删除。

答案 3 :(得分:0)

这里是查看其他本地安装的软件包不需要的软件包的快速解决方案。

library(pacman)
ip <- installed.packages()[,1]
deps <- lapply(1:length(ip), function(i) tryCatch(p_depends(ip[i], local = TRUE)$Imports, error = function(e) return(NULL)))
packages.on.which.things.depend <- sort(unique(unlist(deps)))
packages.on.which.nothing.depends <- setdiff(ip, packages.on.which.things.depend)
packages.on.which.nothing.depends

然后,快速浏览一下并删除不使用的文件(请小心,不要尝试卸载base)。

在确定要使用的和不使用的后,可以进行类似的操作

i.need <- c("AER", "car", "devtools", "glmnet", "gmm", "Hmisc", "pacman", "plm", "RcppArmadillo", "RcppEigen", "rmarkdown", "rugarch", "base", "datasets")
un <- setdiff(packages.on.which.nothing.depends, i.need)
un
remove.packages(un)

漂洗并重复直到没有不需要的孤儿包为止。 R不应该允许您删除内置的系统软件包。