separar todos los paquetes mientras trabaja en R

101

Mientras trabajaba para resolver otro problema, tuve este problema:

Puedo eliminar todos los objetos R por:

rm(list = ls(all = TRUE))

¿Existe un comando equivalente que pueda separar los paquetes instalados durante la sesión de trabajo?

> 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 

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

Intenté de esta manera, aunque incluso funcionó en una solución no 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

Lo que estoy buscando es algo global como:

  rm(list = ls(all = TRUE))

para los objetos, espere que no elimine los paquetes base adjuntos

Gracias;

John Clark
fuente
3
No es que tu pregunta no sea válida, pero ¿por qué no reiniciar R?
Aaron dejó Stack Overflow el
5
@Aaron porque tú tampoco deberías haberlo hecho ;-) R CMD checkSe supone que pasar un paquete se descarga limpiamente, por lo que R Core espera que esto sea posible y algo que uno podría desear hacer.
Gavin Simpson
@ Aaron, creo que en algún momento podría ser útil dejar que la sesión continúe cuando algunos paquetes están causando o podrían causar interferencias, pero se usaron en pasos anteriores ...
John Clark
5
No es posible devolver R a una pizarra nueva. Hablé con John Chambers sobre esto y es particularmente difícil de hacer para el registro de clases / métodos S4.
hadley

Respuestas:

98

Entonces, alguien debería haber respondido simplemente lo siguiente.

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

(edit: 6-28-19) En la última versión de R 3.6.0, utilice en su lugar.

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

Tenga en cuenta que el uso de invisible (*) no es necesario, pero puede ser útil para evitar que la respuesta NULL envíe spam verticalmente a la ventana R.

(editar: 20/9/2019) En la versión 3.6.1

Puede ser útil convertir names(sessionInfo()$loadedOnly)primero los paquetes cargados en paquetes adjuntos explícitamente y, luego, separarlos.

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

Uno puede intentar descargar paquetes base a través de $ basePkgs y también intentar usar unloadNamespace(loadedNamespaces()). Sin embargo, estos suelen estar plagados de errores y podrían romper la funcionalidad básica, como provocar sessionInfo()que se devuelvan solo errores. Esto suele ocurrir debido a la falta de reversibilidad en el diseño del paquete original. Actualmente timeDatepuede romperse de forma irreversible, por ejemplo.

mmfrgmpds
fuente
3
Creo que esto merece votos a favor debido a su simplicidad y no necesita paquetes adicionales.
Antonio Serrano
Esto no funcionó para mí. Lo ejecuté y recibí advertencias, luego ejecuté session.info () todos los paquetes todavía estaban allí.
dxander
1
Sí, en la última versión de R 3.6.0 se debería utilizar lo siguiente en su lugar. invisible (lapply (paste0 ('paquete:', nombres (sessionInfo () $ otherPkgs)), detach, character.only = TRUE, unload = TRUE)) Tenga en cuenta que el uso de invisible (*) no es necesario pero puede evitar el NULL responder desde enviar spam verticalmente a la ventana.
mmfrgmpds
Usar invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE))resultados en un Error in FUN(X[[i]], ...) : invalid 'name' argumenterror
dvanic
El error Error in FUN(X[[i]], ...)...ocurre con frecuencia cuando solo hay un valor NULL presente. Uno puede probar esto con names(sessionInfo()$otherPkgs). Si regresa NULL, entonces esta es la causa.
mmfrgmpds
57

Por favor intente esto:

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
fuente
4
en caso de que te equivoques plyry dplyrparezca el único camino a seguir. ¡Gracias!
JelenaČuklina
29

Estabas cerca. Tenga en cuenta lo que ?detachtiene que decir sobre el primer 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’.

Por lo que debemos llamar repetidamente detach()una vez por elemento de pkg. Hay un par de otros argumentos que debemos especificar para que esto funcione. La primera es character.only = TRUE, que permite que la función asuma que namees una cadena de caracteres; no funcionará sin ella. En segundo lugar, probablemente también queramos descargar cualquier espacio de nombres asociado. Esto se puede lograr configurando unload = TRUE. Entonces la solución es, por ejemplo:

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

Aquí hay un ejemplo 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

Si desea convertir esto en una función, estudie el código sessionInfo()para ver cómo identifica lo que etiqueta como "otros paquetes adjuntos:". Combine ese fragmento de código con la idea anterior en una sola función y estará en casa y seco. Sin embargo, te dejaré esa parte a ti.

Gavin Simpson
fuente
12
puede automatizar esto agregando pkgs = names(sessionInfo()$otherPkgs)ypkgs = paste('package:', pkgs, sep = "")
Ramnath
2
@Ramnath +1 De hecho, pero no quería ser demasiado útil ;-)
Gavin Simpson
4
Es posible que también desee agregar force=TRUEen caso de que los paquetes tengan dependencias.
James
26

nothing

Puede que valga la pena agregar una solución proporcionada por Romain François . Cuando se carga, el paquete nothing, que actualmente está disponible en GitHub , descargará todos los paquetes cargados; como en el ejemplo que ofrece Romain:

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

require(nothing, quietly = TRUE)

loadedNamespaces()
[1] "base"

Instalación

Con el uso del devtoolspaquete:

devtools::install_github("romainfrancois/nothing")

pacman

Un enfoque alternativo utiliza el pacmanpaquete disponible a través de CRAN:

pacman::p_unload(pacman::p_loaded(), character.only = TRUE)
Konrad
fuente
4
Mirar la viñeta ( trinker.github.io/pacman/vignettes/Introduction_to_pacman.html ) ¿quizás pacman::p_unload("all")funcionaría también?
Chandler
10

Sobre la base de la respuesta de Gavin, pero no del todo a una función completa, estaría esta secuencia:

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
fuente
2
de alguna manera puedo hacer lo mismo con una sola línea lapply(paste("package:", names(sessionInfo()$otherPkgs), sep=""), detach, character.only = TRUE, unload = TRUE). ¡Sin embargo, nunca llegaría allí sin tu respuesta!
Ufos
4

o si tiene RStudio, simplemente desmarque todas las casillas marcadas en la pestaña Paquetes para separar

Ajay Ohri
fuente
1
Si tiene muchos paquetes cargados, es complicado desmarcar cada uno 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()

esto asegurará que todos los paquetes se separen, aparte de los paquetes básicos

jazzie
fuente
¿En qué se diferencia esto de la respuesta de
@mjaniec?
1

La mayoría de las veces es el problema plyrvs. dplyrUse esto al principio del código:

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

Entonces, cada vez que se ejecuta el script, borra el plyrpaquete

Prashant
fuente
0

Si tiene problemas con paquetes que tienen funciones con nombres similares en conflicto entre sí, siempre puede hacer referencia al espacio de nombres del paquete cuya función SÍ desea.

pkg_name::function_i_want()
M. Madera
fuente
Este es un comentario en lugar de una respuesta a la pregunta formulada.
Sibo Jiang
Suponga que debería haber establecido esto como comentario en la respuesta anterior de plyr v. Dplyr, ¿es posible moverlo? Todavía estoy aprendiendo las convenciones aquí.
M. Wood
0

La combinación de bits de varias respuestas dio la solución más sólida 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
fuente