odłącz wszystkie pakiety podczas pracy w R

101

Podczas pracy nad rozwiązaniem innego problemu mam ten problem:

Mogę usunąć wszystkie obiekty R poprzez:

rm(list = ls(all = TRUE))

Czy istnieje równoważne polecenie, które może odłączyć zainstalowane pakiety podczas sesji roboczej?

> 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 

wymagają (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 

Próbowałem w ten sposób, chociaż nawet to działało w nie globalnym rozwiązaniu:

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

Szukam czegoś globalnego, takiego jak:

  rm(list = ls(all = TRUE))

dla obiektów, spodziewaj się, że nie usunie dołączonych pakietów podstawowych

dzięki;

John Clark
źródło
3
Nie chodzi o to, że twoje pytanie jest nieważne, ale dlaczego nie po prostu zrestartować R?
Aaron opuścił Stack Overflow
5
@Aaron, bo ty też nie powinieneś ;-) Przekazanie R CMD checkpakietu ma na celu czyste wyładowanie się, więc R Core spodziewa się, że będzie to możliwe i coś, co ktoś chciałby zrobić.
Gavin Simpson
@Aaron, myślę, że czasem może być przydatne zwolnienie sesji, gdy niektóre pakiety powodują lub mogą powodować zakłócenia, ale zostały użyte w poprzednich krokach ...
John Clark
5
Nie można przywrócić R do nowej karty. Rozmawiałem o tym z Johnem Chambersem i jest to szczególnie trudne w przypadku rejestracji klasy / metody S4.
Hadley

Odpowiedzi:

98

Więc ktoś powinien był po prostu odpowiedzieć na następujące pytania.

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

(edycja: 6-28-19) W najnowszej wersji R 3.6.0 użyj zamiast tego.

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

Zauważ, że użycie invisible (*) nie jest konieczne, ale może być przydatne, aby zapobiec blokowaniu przez odpowiedź NULL pionowo okna R.

(edycja: 20.09.2019) W wersji 3.6.1

Pomocne może być names(sessionInfo()$loadedOnly)najpierw przekonwertowanie załadowanych tylko na jawnie dołączone pakiety, a następnie odłączenie tych pakietów.

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

Można spróbować wyładować pakiety podstawowe za pośrednictwem $ basePkgs, a także spróbować użyć unloadNamespace(loadedNamespaces()). Jednak są one zwykle obarczone błędami i mogą powodować uszkodzenie podstawowych funkcji, takich jak sessionInfo()zwracanie tylko błędów. Dzieje się tak zazwyczaj z powodu braku odwracalności w projekcie oryginalnego opakowania. Obecnie timeDatemoże np. Nieodwracalnie się zepsuć.

mmfrgmpds
źródło
3
Myślę, że zasługuje na uznanie ze względu na swoją prostotę i nie wymaga dodatkowych pakietów.
Antonio Serrano
To nie zadziałało dla mnie. Uruchomiłem go, otrzymałem ostrzeżenia, a następnie uruchomiłem session.info (), wszystkie pakiety wciąż tam były.
dxander
1
Tak, w najnowszej wersji R 3.6.0 należy zamiast tego użyć następującego. invisible (lapply (paste0 ('package:', names (sessionInfo () $ otherPkgs)), detach, character.only = TRUE, unload = TRUE)) Zauważ, że użycie invisible (*) nie jest wymagane, ale może zapobiec NULL odpowiedź z pionowego spamowania okna.
mmfrgmpds
Używanie invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE))skutkuje Error in FUN(X[[i]], ...) : invalid 'name' argumentbłędem
dvanic
Błąd Error in FUN(X[[i]], ...)...często występuje, gdy obecna jest tylko wartość NULL. Można to sprawdzić za pomocą names(sessionInfo()$otherPkgs). Jeśli powróci NULL, to jest przyczyna.
mmfrgmpds,
57

Spróbuj tego:

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
źródło
4
w przypadku, gdy zawiedliście plyri dplyrwydaje się, że jest to jedyna droga. Dzięki!
JelenaČuklina
29

Byłeś blisko. Zauważ, co ?detachma do powiedzenia o pierwszy argument namez detach():

Argumenty:

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

Musimy więc wielokrotnie wywoływać detach()raz dla każdego elementu pkg. Jest jeszcze kilka innych argumentów, które musimy określić, aby to zadziałało. Pierwsza tocharacter.only = TRUE , która pozwala funkcji przyjąć, że namejest to ciąg znaków - bez niego nie będzie działać. Po drugie, prawdopodobnie chcemy również zwolnić wszelką powiązaną przestrzeń nazw. Można to osiągnąć poprzez ustawienie unload = TRUE. Tak więc rozwiązaniem jest na przykład:

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

Oto pełny przykład:

> 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

Jeśli chcesz przekształcić to w funkcję, przestudiuj kod, sessionInfo()aby zobaczyć, jak identyfikuje to, co oznacza jako „inne dołączone pakiety:”. Połącz ten fragment kodu z powyższym pomysłem w jednej funkcji, a będziesz suchy. Jednak zostawię to tobie.

Gavin Simpson
źródło
12
możesz to zautomatyzować, dodając pkgs = names(sessionInfo()$otherPkgs)ipkgs = paste('package:', pkgs, sep = "")
Ramnath
2
@Ramnath +1 Rzeczywiście - ale nie chciałem być zbyt pomocny ;-)
Gavin Simpson
4
Możesz również chcieć dodać, force=TRUEjeśli pakiety mają zależności.
James,
26

nothing

Warto dodać rozwiązanie udostępnione przez Romaina François . Po załadowaniu pakiet nothing, który jest obecnie dostępny na GitHub , wyładuje wszystkie załadowane pakiety; jak w przykładzie, który podaje Romain:

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

require(nothing, quietly = TRUE)

loadedNamespaces()
[1] "base"

Instalacja

Przy korzystaniu z devtoolspakietu:

devtools::install_github("romainfrancois/nothing")

pacman

Alternatywne podejście wykorzystuje pacmanpakiet dostępny w CRAN:

pacman::p_unload(pacman::p_loaded(), character.only = TRUE)
Konrad
źródło
4
Patrząc na winietę ( trinker.github.io/pacman/vignettes/Introduction_to_pacman.html ) może też pacman::p_unload("all")by się udało ?
chandler
10

Opierając się na odpowiedzi Gavina, ale niezupełnie do pełnej funkcji, byłaby następująca:

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
źródło
2
jakoś mogę zrobić to samo z linijką lapply(paste("package:", names(sessionInfo()$otherPkgs), sep=""), detach, character.only = TRUE, unload = TRUE). Jednak nigdy nie dotarłbym tam bez twojej odpowiedzi!
Ufos
4

lub jeśli masz RStudio, po prostu odznacz wszystkie zaznaczone pola na karcie Pakiety, aby odłączyć

Ajay Ohri
źródło
1
Jeśli masz dużo załadowanych pakietów, ręczne odznaczanie każdego z nich jest uciążliwe.
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()

zapewni to odłączenie wszystkich pakietów poza pakietami podstawowymi

jazzie
źródło
Czym różni się to od odpowiedzi
@mjaniec
1

W większości przypadków jest to problem z plyrvs. dplyrUżyj tego na początku kodu:

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

Więc za każdym razem, gdy skrypt jest uruchamiany, czyści plyrpakiet

Prashant
źródło
0

Jeśli masz problemy z pakietami, które mają podobnie nazwane funkcje, które są ze sobą w konflikcie, zawsze możesz odwołać się do przestrzeni nazw pakietu, której funkcja, której potrzebujesz.

pkg_name::function_i_want()
M. Wood
źródło
To komentarz zamiast odpowiedzi na zadane pytanie.
Sibo Jiang
Przypuśćmy, że powinienem był ustawić to jako komentarz do poprzedniej odpowiedzi na temat plyr v. Dplyr, czy można to przenieść? Tutaj nadal uczę się konwencji.
M. Wood,
0

Połączenie fragmentów różnych odpowiedzi dało najpotężniejsze rozwiązanie, jakie udało mi się znaleźć ...

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
źródło