desanexe todos os pacotes enquanto trabalha em R

101

Enquanto tentava resolver outro problema, encontrei este problema:

Posso remover todos os objetos R:

rm(list = ls(all = TRUE))

Existe um comando equivalente que pode desanexar pacotes instalados durante a sessão de trabalho?

> 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 

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

Eu tentei dessa forma, embora até funcionasse em uma solução não global:

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

O que estou procurando é algo global como:

  rm(list = ls(all = TRUE))

para objetos, espere que não remova pacotes básicos anexados

obrigado;

John Clark
fonte
3
Não que sua pergunta não seja válida, mas por que não reiniciar o R?
Aaron deixou o Stack Overflow em
5
@Aaron porque você não deveria ter também ;-) Para passar R CMD checkum pacote é necessário descarregar a si mesmo de forma limpa, então o R Core espera que isso seja possível e algo que se queira fazer.
Gavin Simpson,
@Aaron, acho que às vezes pode ser útil deixar a sessão continuar quando alguns pacotes estão causando ou podem causar interferência, mas foram usados ​​nas etapas anteriores ...
John Clark
5
Não é possível retornar R para uma nova lousa. Conversei com John Chambers sobre isso e é particularmente difícil de fazer para o registro de classe / método S4.
hadley

Respostas:

98

Então, alguém deveria simplesmente ter respondido o seguinte.

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

(editar: 6-28-19) Na versão mais recente de R 3.6.0, use.

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

Observe que o uso de invisível (*) não é necessário, mas pode ser útil para evitar que a resposta NULA envie spam verticalmente para a janela R.

(editar: 20/09/2019) Na versão 3.6.1

Pode ser útil primeiro converter carregados apenas names(sessionInfo()$loadedOnly)em pacotes anexados explicitamente e, em seguida, desanexar os pacotes.

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

Pode-se tentar descarregar pacotes básicos via $ basePkgs e também tentar usar unloadNamespace(loadedNamespaces()). No entanto, eles normalmente estão repletos de erros e podem interromper a funcionalidade básica, como fazer sessionInfo()com que retornem apenas erros. Isso normalmente ocorre devido à falta de reversibilidade no design da embalagem original. Atualmente timeDatepode quebrar irreversivelmente, por exemplo.

mmfrgmpds
fonte
3
Acho que isso merece votos positivos devido à sua simplicidade e não precisa de pacotes adicionais.
Antonio Serrano
Isto não funcionou para mim. Eu executei ele obteve avisos, então executei session.info () todos os pacotes ainda estavam lá.
dxander
1
Sim, na versão mais recente do R 3.6.0 deve-se usar o seguinte. invisible (lapply (paste0 ('package:', names (sessionInfo () $ otherPkgs)), detach, character.only = TRUE, unload = TRUE)) Observe que o uso de invisível (*) não é obrigatório, mas pode evitar o NULL responder de spam verticalmente na janela.
mmfrgmpds
Usando invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE))resultados em um Error in FUN(X[[i]], ...) : invalid 'name' argumenterro
dvanic
O erro Error in FUN(X[[i]], ...)...ocorre freqüentemente quando há apenas um valor NULL presente. Pode-se testar isso com names(sessionInfo()$otherPkgs). Se voltar NULL, então esta é a causa.
mmfrgmpds
57

Por favor, tente isto:

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
fonte
4
no caso de você errar plyre dplyrparece ser o único caminho a percorrer. Obrigado!
JelenaČuklina
29

Você estava perto. Observe o que ?detachtem a dizer sobre o primeiro argumento namede detach():

Argumentos:

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

Portanto, precisamos chamar repetidamente detach()uma vez por elemento de pkg. Existem alguns outros argumentos que precisamos especificar para fazer isso funcionar. A primeira é character.only = TRUE, que permite que a função assuma que nameé uma cadeia de caracteres - ela não funcionará sem ela. Em segundo lugar, provavelmente também queremos descarregar qualquer namespace associado. Isso pode ser alcançado definindo unload = TRUE. Portanto, a solução é, por exemplo:

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

Aqui está um exemplo completo:

> 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

Se você quiser transformar isso em uma função, estude o código sessionInfo()para ver como ele identifica o que rotula como "outros pacotes anexados:". Combine esse trecho de código com a ideia acima em uma única função e você estará em casa e seco. Vou deixar isso com você.

Gavin Simpson
fonte
12
você pode automatizar isso adicionando pkgs = names(sessionInfo()$otherPkgs)epkgs = paste('package:', pkgs, sep = "")
Ramnath
2
@Ramnath +1 Certamente - mas eu não queria ser muito útil ;-)
Gavin Simpson
4
Você também pode querer adicionar force=TRUEcaso os pacotes tenham dependências.
James,
26

nothing

Pode valer a pena adicionar solução disponibilizada por Romain François . Quando carregado, o pacote nothing, que está atualmente disponível no GitHub , descarregará todos os pacotes carregados; como no exemplo que Romain fornece:

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

require(nothing, quietly = TRUE)

loadedNamespaces()
[1] "base"

Instalação

Com o uso do devtoolspacote:

devtools::install_github("romainfrancois/nothing")

pacman

Uma abordagem alternativa usa o pacmanpacote disponível através do CRAN:

pacman::p_unload(pacman::p_loaded(), character.only = TRUE)
Konrad
fonte
4
Olhar para a vinheta ( trinker.github.io/pacman/vignettes/Introduction_to_pacman.html ) talvez pacman::p_unload("all")funcione bem?
chandler
10

Com base na resposta de Gavin, mas não totalmente para uma função completa, seria esta sequência:

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)
IRTFM
fonte
2
de alguma forma, posso fazer o mesmo com um one-liner lapply(paste("package:", names(sessionInfo()$otherPkgs), sep=""), detach, character.only = TRUE, unload = TRUE). Nunca chegaria lá sem a sua resposta!
Ufos
4

ou se você tiver RStudio, simplesmente desmarque todas as caixas marcadas na guia Pacotes para desanexar

Ajay Ohri
fonte
1
Se você tiver muitos pacotes carregados, é complicado desmarcar cada um manualmente.
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()

isto irá garantir que todos os pacotes sejam separados dos seus pacotes básicos

jazzie
fonte
Como isso é diferente da resposta de
@mjaniec
1

Na maioria das vezes é o problema plyrvs. dplyrUse isso no início do código:

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

Assim, sempre que o script é executado, ele limpa o plyrpacote

Prashant
fonte
0

se estiver tendo problemas com pacotes que têm funções nomeadas de forma semelhante conflitantes entre si, você sempre pode fazer referência ao namespace do pacote cuja função você deseja.

pkg_name::function_i_want()
M. Wood
fonte
Este é um comentário em vez de uma resposta à pergunta feita.
Sibo Jiang
Suponha que eu deva ter definido isso como comentário para a resposta anterior plyr x dplyr, é possível movê-lo? Ainda estou aprendendo as convenções aqui.
M. Wood
0

Combinar bits de várias respostas deu a solução mais robusta que pude encontrar ...

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)
  }
}
Charlie
fonte