отсоединить все пакеты при работе в R


101

Работая над решением другой проблемы, у меня возникла эта проблема:

Я могу удалить все объекты 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))

для объектов ожидайте, что он не удалит прикрепленные базовые пакеты

Спасибо;


3
Не то чтобы ваш вопрос недействителен, но почему бы просто не перезапустить R?
Аарон покинул Stack Overflow

5
@Aaron, потому что у вас тоже не должно быть ;-) Чтобы передать R CMD checkпакет, предполагается, что он полностью выгружается, поэтому R Core ожидает, что это возможно, и что-то, что можно было бы сделать.
Гэвин Симпсон

@Aaron, я думаю, что когда-нибудь было бы полезно разрешить сеанс, когда некоторые пакеты вызывают или могут вызывать помехи, но использовались на предыдущих шагах ...
Джон Кларк

5
Невозможно вернуть R на новый уровень. Я говорил об этом с Джоном Чемберсом, и это особенно сложно сделать для регистрации класса / метода S4.
hadley

Ответы:


100

Итак, кто-то должен был просто ответить следующее.

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 (*) не обязательно, но может быть полезно для предотвращения вертикального спама в R-окне ответом NULL.

(редактировать: 20.09.2019) В версии 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может, например, сломаться безвозвратно.


3
Я думаю, что это заслуживает одобрения из-за своей простоты и не требует дополнительных пакетов.
Антонио Серрано

У меня это не сработало. Я запустил его, получил предупреждения, затем запустил session.info (), все пакеты были там.
dxander

1
Да, в последней версии R 3.6.0 вместо этого следует использовать следующее. invisible (lapply (paste0 ('package:', names (sessionInfo () $ otherPkgs)), detach, character.only = TRUE, unload = TRUE)) Обратите внимание, что использование invisible (*) не требуется, но может предотвратить NULL ответ от вертикального спама окна.
mmfrgmpds

Использование invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE))результатов в Error in FUN(X[[i]], ...) : invalid 'name' argumentошибке
dvanic

Ошибка Error in FUN(X[[i]], ...)...часто возникает, когда присутствует только значение NULL. Проверить это можно с помощью names(sessionInfo()$otherPkgs). Если он вернется NULL, значит, это причина.
mmfrgmpds

57

Пожалуйста, попробуйте это:

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

4
в случае, если вы напортачили plyrи dplyrкажется, что это единственный выход. Спасибо!
JelenaČuklina

29

Вы были близки. Обратите внимание , что ?detachдолжно сказать о первом аргументе nameиз detach():

Аргументы:

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’.

Поэтому нам нужно многократно вызывать detach()один раз для каждого элемента pkg. Есть еще пара аргументов, которые нам нужно указать, чтобы это работало. Во-первых 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()чтобы увидеть, как он идентифицирует то, что помечает как «другие прикрепленные пакеты:». Объедините этот фрагмент кода с идеей, описанной выше, в одной функции, и вы дома и сухо. Я оставлю это на ваше усмотрение.


12
вы можете автоматизировать это, добавив pkgs = names(sessionInfo()$otherPkgs)иpkgs = paste('package:', pkgs, sep = "")
Рамнат

2
@Ramnath +1 Действительно, но я не хотел быть слишком полезным ;-)
Гэвин Симпсон

4
Вы также можете добавить, force=TRUEесли у пакетов есть зависимости.
Джеймс

26

nothing

Возможно, стоит добавить решение, предоставленное Роменом Франсуа . При загрузке пакет nothing, который в настоящее время доступен на GitHub , выгружает все загруженные пакеты; как в примере, который предоставляет Ромен:

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

require(nothing, quietly = TRUE)

loadedNamespaces()
[1] "base"

Монтаж

При использовании devtoolsпакета:

devtools::install_github("romainfrancois/nothing")

pacman

Альтернативный подход использует pacmanпакет, доступный через CRAN:

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

4
Глядя на виньетку ( trinker.github.io/pacman/vignettes/Introduction_to_pacman.html ), может быть, pacman::p_unload("all")тоже подойдет ?
chandler

10

Основываясь на ответе Гэвина, но не в полной мере, это будет следующая последовательность:

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)

2
как-то я могу сделать то же самое с однострочником lapply(paste("package:", names(sessionInfo()$otherPkgs), sep=""), detach, character.only = TRUE, unload = TRUE). Но без вашего ответа я бы туда не попал!
Ufos

4

или если у вас есть RStudio, просто снимите все флажки на вкладке «Пакеты», чтобы отсоединить


1
Если у вас много загруженных пакетов, то вручную снимать флажки у каждого из них затруднительно.
Sibo Jiang

3
#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

1

В большинстве случаев это проблема plyrvs. dplyrИспользуйте это в начале кода:

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

Поэтому всякий раз, когда запускается скрипт, он очищает plyrпакет


0

если у вас возникли проблемы с пакетами, в которых функции с одинаковыми именами конфликтуют друг с другом, вы всегда можете сослаться на пространство имен пакета, функция которого вам нужна.

pkg_name::function_i_want()

Это комментарий, а не ответ на заданный вопрос.
Sibo Jiang

Предположим, я должен был установить это как комментарий к предыдущему ответу plyr v. Dplyr, можно ли его переместить? Я все еще изучаю здесь условности.
M. Wood

0

Объединение битов из разных ответов дало самое надежное решение, которое я смог найти ...

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)
  }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.