від'єднайте всі пакунки під час роботи в 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?
Аарон вийшов із переповнення стека

5
@Aaron, тому що у вас не повинно бути занадто ;-) Для передачі R CMD checkпакету належить чисто розвантажити себе, тому R Core очікує, що це стане можливим, і щось, можливо, захочеться зробити.
Гевін Сімпсон

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

5
Повернути R до свіжого сланця неможливо. Я говорив з Джоном Чемберсом про це, і це особливо важко зробити для реєстрації класу / методу S4.
Хадлі

Відповіді:


98

Отже, хтось повинен був просто відповісти на наступне.

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

Зверніть увагу, що використання невидимого (*) не є необхідним, але може бути корисним для запобігання вертикальної спаму 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 слід використовувати наступну. невидимий (lapply (paste0 ('пакунок:', імена (sessionInfo () $ otherPkgs)), відокремлення, характер.only = TRUE, unload = TRUE)) Зверніть увагу, що використання невидимого (*) не потрібно, але може запобігти 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 = "")
Ramnath

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")це також спрацює?
Чендлер

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, просто зніміть прапорці з усіх відмічених прапорів на вкладці Packages, щоб від'єднатись


1
Якщо у вас багато завантажених пакетів, неможливо зняти галочку кожного вручну.
Сібо Цзян

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

Більшість разів це plyrпроти dplyrвипуску. Скористайтеся цим на початку коду:

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

Отже, коли сценарій запускається, він очищає plyrпакет


0

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

pkg_name::function_i_want()

Це коментар замість відповіді на поставлене запитання.
Сібо Цзян

Припустимо, я мав би встановити це як коментар до попередньої відповіді plyr v. Dplyr, чи можливо це перемістити? Я все ще вчуся тут умовам.
М. Вуд

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.