在 R 中工作时分离所有包

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

我可以通过以下方法移除所有 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))

对于对象,希望它不会删除附加的基本包

谢谢;

99156 次浏览

注意 ?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()中的代码,看看它是如何识别它标记为“其他附加包:”。将这些代码和上面的想法结合在一个函数中,你就可以回家了。不过这事还是交给你了。

Building on Gavin's answer but not quite to a full function would be this sequence:

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)

请试试这个:

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()

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

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

(编辑: 6-28-19) 在 R3.6.0的最新版本中,请使用。

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

注意,使用不可见(*)是没有必要的,但是可以有效地防止 NULL 应答对 R 窗口产生垂直垃圾邮件。

(编辑: 9/20/2019) In version 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))

One can attempt to unload base packages via $basePkgs and also attempt using unloadNamespace(loadedNamespaces()). However these typically are fraught with errors and could break basic functionality such as causing sessionInfo() to return only errors. This typically occurs because of a lack of reversibility in the original package's design. Currently timeDate can break irreversibly, for example.

版本4.0.2(编辑: 9/24/20) 下面首先加载要测试的包,然后给出一个序列来完全分离除包“ 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).

nothing

这可能是值得添加的解决方案提供的 罗曼・弗朗索瓦。当加载包 强 > nothing(目前在 GitHub上可用)时,将卸载所有加载的包; 如 Romain 提供的示例所示:

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


require(nothing, quietly = TRUE)


loadedNamespaces()
[1] "base"

安装

With use of the 强 > devtools package:

devtools::install_github("romainfrancois/nothing")

pacman

另一种方法是使用通过 CRAN 提供的 强 > pacman软件包:

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

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

大多数情况下是 plyrdplyr的问题。在代码的开头使用这个:

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

因此,只要脚本运行,它就会清除 plyr

如果遇到包名称相似的函数之间相互冲突的问题,总是可以引用包的名称空间,这个名称空间就是您想要的函数。

pkg_name::function_i_want()

综合各种答案的结果给出了我能找到的最有力的解决方案。

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)
}
}
#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()

this will make sure all packages gets detached apart from your basic packages

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

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)