Trennen Sie alle Pakete, während Sie in R arbeiten

101

Während ich daran arbeitete, ein anderes Problem zu lösen, bekam ich dieses Problem:

Ich kann alle R-Objekte entfernen durch:

rm(list = ls(all = TRUE))

Gibt es einen entsprechenden Befehl, mit dem installierte Pakete während der Arbeitssitzung getrennt werden können?

> 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 

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

Ich habe es auf diese Weise versucht, obwohl es in keiner globalen Lösung funktioniert hat:

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

Was ich suche, ist etwas Globales wie:

  rm(list = ls(all = TRUE))

Erwarten Sie für Objekte, dass angehängte Basispakete nicht entfernt werden

Vielen Dank;

John Clark
quelle
3
Nicht dass Ihre Frage nicht gültig wäre, aber warum nicht einfach R neu starten?
Aaron verließ Stack Overflow
5
@ Aaron, weil du es nicht auch haben solltest ;-) Um R CMD checkein Paket zu übergeben, soll es sich sauber entladen, also erwartet R Core, dass dies möglich ist und etwas, das man vielleicht tun möchte.
Gavin Simpson
@ Aaron, ich denke, irgendwann kann es nützlich sein, die Sitzung laufen zu lassen, wenn einige Pakete Störungen verursachen oder verursachen, aber in den vorherigen Schritten verwendet wurden ...
John Clark
5
Es ist nicht möglich, R auf eine frische Tafel zurückzubringen. Ich habe mit John Chambers darüber gesprochen, und es ist besonders schwierig, dies für die Registrierung von S4-Klassen / Methoden zu tun.
Hadley

Antworten:

98

Also hätte jemand einfach folgendes beantworten sollen.

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

(bearbeiten: 28.06.19) In der neuesten Version von R 3.6.0 verwenden Sie bitte stattdessen.

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

Beachten Sie, dass die Verwendung von unsichtbar (*) nicht erforderlich ist, aber nützlich sein kann, um zu verhindern, dass die NULL-Antwort das R-Fenster vertikal spammt.

(Bearbeiten: 20.09.2019) In Version 3.6.1

Es kann hilfreich sein, geladene names(sessionInfo()$loadedOnly)Pakete zuerst nur in explizit angehängte Pakete zu konvertieren und dann die Pakete zu trennen.

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

Man kann sich über $ basePkgs zu entladen Basispakete versuchen , und auch versuchen , mit unloadNamespace(loadedNamespaces()). Diese sind jedoch in der Regel mit Fehlern behaftet und können grundlegende Funktionen beeinträchtigen, z. B. sessionInfo()nur Fehler zurückgeben. Dies tritt typischerweise aufgrund einer mangelnden Reversibilität im Design der Originalverpackung auf. Derzeit timeDatekann zum Beispiel irreversibel brechen.

mmfrgmpds
quelle
3
Ich denke, dies verdient aufgrund seiner Einfachheit positive Stimmen und benötigt keine zusätzlichen Pakete.
Antonio Serrano
Das hat bei mir nicht funktioniert. Ich lief es bekam Warnungen, dann lief session.info () alle Pakete waren noch da.
Dxander
1
Ja, in der neuesten Version von R 3.6.0 sollte stattdessen Folgendes verwendet werden. unsichtbar (lapply (paste0 ('package:', names (sessionInfo () $ otherPkgs)), separate, character.only = TRUE, unload = TRUE)) Beachten Sie, dass die Verwendung von unsichtbar (*) nicht erforderlich ist, aber NULL verhindern kann Antwort von vertikalem Spammen des Fensters.
mmfrgmpds
Verwenden von invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE))Ergebnissen in einem Error in FUN(X[[i]], ...) : invalid 'name' argumentFehler
dvanic
Der Fehler Error in FUN(X[[i]], ...)...tritt häufig auf, wenn nur ein NULL-Wert vorhanden ist. Man kann das mit testen names(sessionInfo()$otherPkgs). Wenn es zurückkehrt NULL, ist dies die Ursache.
mmfrgmpds
57

Bitte versuchen Sie dies:

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
quelle
4
Für den Fall, dass Sie es vermasselt haben plyrund dplyres scheint der einzige Weg zu sein. Vielen Dank!
JelenaČuklina
29

Du warst nah. Beachten Sie, was ?detachzu dem ersten Argument namevon zu sagen ist detach():

Argumente:

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

Wir müssen also wiederholt detach()einmal pro Element von aufrufen pkg. Es gibt noch einige andere Argumente, die wir angeben müssen, damit dies funktioniert. Das erste ist character.only = TRUE, dass die Funktion annehmen kann, dass namees sich um eine Zeichenfolge handelt - ohne sie funktioniert es nicht. Zweitens möchten wir wahrscheinlich auch den zugehörigen Namespace entladen. Dies kann durch Einstellen erreicht werden unload = TRUE. Die Lösung lautet also zum Beispiel:

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

Hier ist ein vollständiges Beispiel:

> 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

Wenn Sie dies in eine Funktion umwandeln möchten, lesen Sie den Code sessionInfo(), um festzustellen, wie er die Kennzeichnung als "andere angehängte Pakete:" identifiziert. Kombinieren Sie diesen Code mit der obigen Idee in einer einzigen Funktion und Sie sind zu Hause und trocken. Das überlasse ich dir allerdings.

Gavin Simpson
quelle
12
Sie können dies automatisieren, indem Sie pkgs = names(sessionInfo()$otherPkgs)undpkgs = paste('package:', pkgs, sep = "")
Ramnath
2
@ Ramnath +1 In der Tat - aber ich wollte nicht zu hilfreich sein ;-)
Gavin Simpson
4
Sie können auch hinzufügen, force=TRUEfalls die Pakete Abhängigkeiten aufweisen.
James
26

nothing

Es kann sich lohnen, eine von Romain François zur Verfügung gestellte Lösung hinzuzufügen . Beim Laden entlädt das Paket nothing, das derzeit auf GitHub verfügbar ist , alle geladenen Pakete. wie in dem Beispiel, das Romain liefert:

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

require(nothing, quietly = TRUE)

loadedNamespaces()
[1] "base"

Installation

Bei Verwendung des devtoolsPakets:

devtools::install_github("romainfrancois/nothing")

pacman

Ein alternativer Ansatz verwendet ein pacmanüber CRAN verfügbares Paket:

pacman::p_unload(pacman::p_loaded(), character.only = TRUE)
Konrad
quelle
4
Ein Blick auf die Vignette ( trinker.github.io/pacman/vignettes/Introduction_to_pacman.html ) pacman::p_unload("all")würde vielleicht auch funktionieren?
Chandler
10

Aufbauend auf Gavins Antwort, aber nicht ganz zu einer vollen Funktion, wäre diese Sequenz:

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
quelle
2
Irgendwie kann ich das auch mit einem Einzeiler machen lapply(paste("package:", names(sessionInfo()$otherPkgs), sep=""), detach, character.only = TRUE, unload = TRUE). Würde ohne deine Antwort niemals dorthin gelangen!
Ufos
4

Wenn Sie über RStudio verfügen, deaktivieren Sie einfach alle Kontrollkästchen auf der Registerkarte "Pakete", um die Verbindung zu trennen

Ajay Ohri
quelle
1
Wenn Sie viele Pakete geladen haben, ist es umständlich, alle manuell zu deaktivieren.
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()

Dadurch wird sichergestellt, dass alle Pakete außer Ihren Basispaketen getrennt werden

jazzie
quelle
Wie unterscheidet sich das von @mjaniec Antwort
StupidWolf
1

Meistens ist es das plyrvs- dplyrProblem. Verwenden Sie dies am Anfang des Codes:

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

Wenn das Skript ausgeführt wird, wird das plyrPaket gelöscht

Prashant
quelle
0

Wenn Sie Probleme mit Paketen haben, deren Funktionen ähnlich benannte Funktionen in Konflikt miteinander stehen, können Sie immer auf den Namespace des Pakets verweisen, dessen Funktion Sie möchten.

pkg_name::function_i_want()
M. Wood
quelle
Dies ist ein Kommentar anstelle einer Antwort auf die gestellte Frage.
Sibo Jiang
Angenommen, ich hätte dies als Kommentar zur vorherigen Antwort von plyr v. Dplyr festlegen sollen. Ist es möglich, es zu verschieben? Ich lerne hier immer noch die Konventionen.
M. Wood
0

Das Kombinieren von Bits aus verschiedenen Antworten ergab die robusteste Lösung, die ich finden konnte ...

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
quelle