【问题标题】:detach all packages while working in R在 R 中工作时分离所有包
【发布时间】:2011-11-22 06:18:18
【问题描述】:

在解决另一个问题时遇到了这个问题:

我可以通过以下方式删除所有 R 对象:

rm(list = ls(all = TRUE))

是否有等效的命令可以在工作会话期间分离已安装的包?

> sessionInfo()
R version 2.12.2 (2011-02-25)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base 

需要(ggplot2)

Loading required package: ggplot2
Loading required package: reshape
Loading required package: plyr

Attaching package: 'reshape'

The following object(s) are masked from 'package:plyr':

    round_any

Loading required package: grid
Loading required package: proto

sessionInfo()

R version 2.12.2 (2011-02-25)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods  
[8] base     

other attached packages:
[1] ggplot2_0.8.9 proto_0.3-9.1 reshape_0.8.4 plyr_1.4 

我尝试过这种方式,尽管它在不是全局解决方案中也有效:

pkg <- c("package:ggplot2_0.8.9", "package:proto_0.3-9.1", "package:reshape_0.8.4",  "package:plyr_1.4")

 detach(pkg, character.only = TRUE)

Error in detach(pkg, character.only = TRUE) : invalid 'name' argument
In addition: Warning message:
In if (is.na(pos)) stop("invalid 'name' argument") :
  the condition has length > 1 and only the first element will be used

我正在寻找的是全球性的,例如:

  rm(list = ls(all = TRUE))

对于对象,期望它不会删除附加的基础包

谢谢;

【问题讨论】:

  • 不是你的问题是无效的,而是为什么不重启R?
  • @Aaron 因为你不应该有太多 ;-) 传递R CMD check 一个包应该干净地卸载自己,所以 R Core 期望这是可能的,并且可能希望这样做。
  • @Aaron,我认为有时在某些包引起或可能引起干扰时让会话继续可能很有用,但在前面的步骤中使用...
  • 不可能将 R 恢复到新的状态。我已经和 John Chambers 讨论过这个问题,对于 S4 类/方法注册来说尤其困难。

标签: r workspace


【解决方案1】:

所以,应该有人简单地回答了以下问题。

lapply(paste('package:',names(sessionInfo()$otherPkgs),sep=""),detach,character.only=TRUE,unload=TRUE)

(编辑:6-28-19) 在最新版本的 R 3.6.0 中请改用。

invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE))

注意,invisible(*) 的使用不是必需的,但可以用于防止 NULL 回复垂直向 R 窗口发送垃圾邮件。

(编辑:2019 年 9 月 20 日)在 3.6.1 版中

先将仅加载的 names(sessionInfo()$loadedOnly) 转换为显式附加的包,然后再分离这些包,这样可能会有所帮助。

lapply(names(sessionInfo()$loadedOnly), require, character.only = TRUE)
invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE, force=TRUE))

可以尝试通过 $basePkgs 卸载基础包,也可以尝试使用unloadNamespace(loadedNamespaces())。然而,这些通常充满错误并且可能会破坏基本功能,例如导致sessionInfo() 仅返回错误。这通常是由于原始包装的设计缺乏可逆性而发生的。例如,目前timeDate 可以不可逆地中断。

(编辑:2020 年 9 月 24 日)4.0.2 版 下面首先加载要测试的包,然后给出一个序列来完全分离除包“base”和“utils”之外的所有包。强烈建议不要分离这些包。

    invisible(suppressMessages(suppressWarnings(lapply(c("gsl","fBasics","stringr","stringi","Rmpfr"), require, character.only = TRUE))))
    invisible(suppressMessages(suppressWarnings(lapply(names(sessionInfo()$loadedOnly), require, character.only = TRUE))))
    sessionInfo()

    #the above is a test

    invisible(lapply(paste0('package:', c("stringr","fBasics")), detach, character.only=TRUE,unload=TRUE))
    #In the line above, I have inserted by hand what I know the package dependencies to be. A user must know this a priori or have their own automated
    #method to discover it. Without removing dependencies first, the user will have to cycle through loading namespaces and then detaching otherPkgs a
    #second time through.
    invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE,unload=TRUE))

    bspkgs.nb<-sessionInfo()$basePkgs[sessionInfo()$basePkgs!="base"]
    bspkgs.nbu<-bspkgs.nb[bspkgs.nb!="utils"]
    names(bspkgs.nbu)<-bspkgs.nbu
    suppressMessages(invisible(lapply(paste0('package:', names(bspkgs.nbu)), detach, character.only=TRUE,unload=TRUE)))

    #again this thoroughly removes all packages and loaded namespaces except for base packages "base" and "utils" (which is highly not recommended).

【讨论】:

  • 我认为这值得点赞,因为它很简单,不需要额外的包。
  • 这对我不起作用。我运行它得到警告,然后运行 ​​session.info() 所有包仍然存在。
  • 是的,在最新版本的 R 3.6.0 中,应该使用以下内容。 invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE)) 注意使用 invisible(*) 不是必需的,但可以防止 NULL从垂直向窗口发送垃圾邮件回复。
  • 使用invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE)) 会导致Error in FUN(X[[i]], ...) : invalid 'name' argument 错误
  • 错误Error in FUN(X[[i]], ...)... 经常发生在只存在一个NULL 值时。可以使用names(sessionInfo()$otherPkgs) 对此进行测试。如果它返回NULL,那么这就是原因。
【解决方案2】:

请试试这个:

detachAllPackages <- function() {

  basic.packages <- c("package:stats","package:graphics","package:grDevices","package:utils","package:datasets","package:methods","package:base")

  package.list <- search()[ifelse(unlist(gregexpr("package:",search()))==1,TRUE,FALSE)]

  package.list <- setdiff(package.list,basic.packages)

  if (length(package.list)>0)  for (package in package.list) detach(package, character.only=TRUE)

}

detachAllPackages()

【讨论】:

  • 如果你搞砸了plyr & dplyr,这似乎是唯一的出路。谢谢!
  • 这适用于 R 4.0.2,而其他解决方案似乎不适用于
【解决方案3】:

你很亲密。注意?detachdetach() 的第一个参数name 的看法:

参数:

name: The object to detach.  Defaults to ‘search()[pos]’.  This can
      be an unquoted name or a character string but _not_ a
      character vector.  If a number is supplied this is taken as
      ‘pos’.

所以我们需要对pkg 的每个元素重复调用一次detach()。我们需要指定几个其他参数才能使其正常工作。第一个是character.only = TRUE,它允许函数假定name 是一个字符串——没有它就无法工作。其次,我们可能还想卸载任何关联的命名空间。这可以通过设置unload = TRUE 来实现。所以解决方案是,例如:

pkg <- c("package:vegan","package:permute")
lapply(pkg, detach, character.only = TRUE, unload = TRUE)

这是一个完整的例子:

> require(vegan)
Loading required package: vegan
Loading required package: permute
This is vegan 2.0-0
> sessionInfo()
R version 2.13.1 Patched (2011-09-13 r57007)
Platform: x86_64-unknown-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_GB.utf8       LC_NUMERIC=C             
 [3] LC_TIME=en_GB.utf8        LC_COLLATE=en_GB.utf8    
 [5] LC_MONETARY=C             LC_MESSAGES=en_GB.utf8   
 [7] LC_PAPER=en_GB.utf8       LC_NAME=C                
 [9] LC_ADDRESS=C              LC_TELEPHONE=C           
[11] LC_MEASUREMENT=en_GB.utf8 LC_IDENTIFICATION=C      

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

other attached packages:
[1] vegan_2.0-0   permute_0.7-0

loaded via a namespace (and not attached):
[1] grid_2.13.1     lattice_0.19-33 tools_2.13.1   
> pkg <- c("package:vegan","package:permute")
> lapply(pkg, detach, character.only = TRUE, unload = TRUE)
[[1]]
NULL

[[2]]
NULL

> sessionInfo()
R version 2.13.1 Patched (2011-09-13 r57007)
Platform: x86_64-unknown-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_GB.utf8       LC_NUMERIC=C             
 [3] LC_TIME=en_GB.utf8        LC_COLLATE=en_GB.utf8    
 [5] LC_MONETARY=C             LC_MESSAGES=en_GB.utf8   
 [7] LC_PAPER=en_GB.utf8       LC_NAME=C                
 [9] LC_ADDRESS=C              LC_TELEPHONE=C           
[11] LC_MEASUREMENT=en_GB.utf8 LC_IDENTIFICATION=C      

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

loaded via a namespace (and not attached):
[1] grid_2.13.1     lattice_0.19-33 tools_2.13.1

如果你想把它变成一个函数,请研究sessionInfo() 中的代码,看看它如何识别它标记为“其他附加包:”的内容。将那段代码与上面的想法结合在一个函数中,你就可以回家了。不过,我会留给你。

【讨论】:

  • 您可以通过添加 pkgs = names(sessionInfo()$otherPkgs)pkgs = paste('package:', pkgs, sep = "") 来自动执行此操作
  • @Ramnath +1 确实 - 但我不想乐于助人;-)
  • 你可能还想添加force=TRUE,以防包有依赖关系。
【解决方案4】:

nothing

可能值得添加Romain François 提供的解决方案。当加载包nothing(当前在GitHub 上可用)时,将卸载所有加载的包;如 Romain 提供的示例:

loadedNamespaces()
[1] "base"      "datasets"  "grDevices" "graphics"  "methods"   "stats"
[7] "utils"

require(nothing, quietly = TRUE)

loadedNamespaces()
[1] "base"

安装

使用devtools 包:

devtools::install_github("romainfrancois/nothing")

pacman

另一种方法是使用可通过 CRAN 获得的 pacman 包:

pacman::p_unload(pacman::p_loaded(), character.only = TRUE)

【讨论】:

【解决方案5】:

以 Gavin 的回答为基础,但不完全是这样的序列:

sess.pkgs <- function (package = NULL) 
{   z <- list()
       if (is.null(package)) {
        package <- grep("^package:", search(), value = TRUE)
        keep <- sapply(package, function(x) x == "package:base" || 
            !is.null(attr(as.environment(x), "path")))
        package <- sub("^package:", "", package[keep])
    }
    pkgDesc <- lapply(package, packageDescription)
    if (length(package) == 0) 
        stop("no valid packages were specified")
    basePkgs <- sapply(pkgDesc, function(x) !is.null(x$Priority) && 
        x$Priority == "base")
    z$basePkgs <- package[basePkgs]
    if (any(!basePkgs)) {
        z$otherPkgs <-  package[!basePkgs]
    }
    z
}

lapply(paste("package:",sess.pkgs()$otherPkgs, sep=""), detach, 
                             character.only = TRUE, unload = TRUE)

【讨论】:

  • 不知何故我可以用单线lapply(paste("package:", names(sessionInfo()$otherPkgs), sep=""), detach, character.only = TRUE, unload = TRUE)做同样的事情。没有你的答案永远不会到达那里!
【解决方案6】:

或者如果您有 RStudio,只需取消选中 Packages Tab 中的所有复选框即可分离

【讨论】:

  • 如果你有很多加载的包,手动取消每一个是很麻烦的。
【解决方案7】:
#Detach all  packages
detachAllPackages <- function() {

  basic.packages <- c("package:stats","package:graphics","package:grDevices","package:utils","package:datasets","package:methods","package:base")

  package.list <- search()[ifelse(unlist(gregexpr("package:",search()))==1,TRUE,FALSE)]

  package.list <- setdiff(package.list,basic.packages)

  if (length(package.list)>0)  for (package in package.list) detach(package, character.only=TRUE)

}

detachAllPackages()

这将确保所有包都与您的基本包分离

【讨论】:

  • 这与@mjaniec 回答有何不同
【解决方案8】:

大多数时候是 plyrdplyr 的问题。在代码开头使用这个:

detach("package:plyr", unload=TRUE)

因此,每当脚本运行时,它都会清除 plyr

【讨论】:

    【解决方案9】:

    结合来自各种答案的位给出了我能找到的最强大的解决方案...

    packs <- c(names(sessionInfo()$otherPkgs), names(sessionInfo()$loadedOnly))
    if(length(packs) > 0){ 
      message('Unloading packages -- if any problems occur, please try this from a fresh R session')
      while(length(packs) > 0){
        newpacks <- c()
        for(packi in 1:length(packs)){
          u=try(unloadNamespace(packs[packi]))
          if(class(u) %in% 'try-error') newpacks <- c(newpacks,packs[packi])
        }
        packs <- newpacks
        Sys.sleep(.1)
      }
    }
    

    【讨论】:

      【解决方案10】:

      为什么不在下面删除所有附加的包?

      intialPackages = search() # added as 1st line of R script to get list of default packages
      # below lines are added when newly attached packages needs to be removed
      newPackages = search()[!(search() %in% intialPackages)]
      try(sapply(newPackages, detach, character.only=TRUE, unload=TRUE, force=TRUE), silent=TRUE)
      

      【讨论】:

        【解决方案11】:

        如果您在使用具有相似名称的函数相互冲突的包时遇到问题,您始终可以引用您想要的函数的包的命名空间。

        pkg_name::function_i_want()
        

        【讨论】:

        • 这是评论而不是对所提问题的回答。
        • 假设我应该将此设置为对先前 plyr v. dplyr 答案的评论,是否可以移动它?我还在学习这里的约定。
        猜你喜欢
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 1970-01-01
        • 2016-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-19
        相关资源
        最近更新 更多