ถอดแพ็คเกจทั้งหมดขณะทำงานใน R


103

ในขณะที่ทำงานเพื่อแก้ไขปัญหาอื่นฉันพบปัญหานี้:

ฉันสามารถลบวัตถุ 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
Aaron ออกจาก Stack Overflow

5
@Aaron เพราะคุณไม่ควรมีเช่นกัน ;-) ในการส่งผ่านR CMD checkแพ็คเกจควรจะยกเลิกการโหลดตัวเองอย่างหมดจดดังนั้น R Core จึงคาดหวังว่าสิ่งนี้จะเป็นไปได้และบางสิ่งบางอย่างอาจต้องการทำ
Gavin Simpson

@Aaron ฉันคิดว่าบางครั้งมันอาจจะมีประโยชน์ที่จะปล่อยให้เซสชั่นดำเนินไปเมื่อแพ็คเกจบางอย่างก่อให้เกิดหรืออาจทำให้เกิดการรบกวน แต่ถูกใช้ในขั้นตอนก่อนหน้านี้ ...
John Clark

6
ไม่สามารถคืนค่า R เป็นกระดานชนวนใหม่ได้ ฉันได้พูดคุยกับ John Chambers เกี่ยวกับเรื่องนี้แล้วและเป็นการยากโดยเฉพาะอย่างยิ่งสำหรับการลงทะเบียนคลาส / วิธีการ S4
hadley

คำตอบ:


103

ดังนั้นใครบางคนควรจะตอบคำถามต่อไปนี้

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

โปรดทราบว่าการใช้ล่องหน (*) ไม่จำเป็น แต่จะมีประโยชน์ในการป้องกันการตอบกลับ NULL จากการสแปมหน้าต่าง R ในแนวตั้ง

(แก้ไข: 9/20/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สามารถทำลายกลับไม่ได้เช่น

(แก้ไข: 9/24/20) สำหรับเวอร์ชัน 4.0.2 ต่อไปนี้จะโหลดแพ็กเกจแรกเพื่อทดสอบจากนั้นให้ลำดับในการแยกแพ็กเกจทั้งหมดออกทั้งหมดยกเว้นแพ็กเกจ "ฐาน" และ "ยูทิลิตี้" ขอแนะนำอย่างยิ่งว่าอย่าถอดหีบห่อเหล่านั้นออก

    invisible(suppressMessages(suppressWarnings(lapply(c("gsl","fBasics","stringr","stringi","Rmpfr"), require, character.only = TRUE))))
    invisible(suppressMessages(suppressWarnings(lapply(names(sessionInfo()$loadedOnly), require, character.only = TRUE))))
    sessionInfo()

    #the above is a test

    invisible(lapply(paste0('package:', c("stringr","fBasics")), detach, character.only=TRUE,unload=TRUE))
    #In the line above, I have inserted by hand what I know the package dependencies to be. A user must know this a priori or have their own automated
    #method to discover it. Without removing dependencies first, the user will have to cycle through loading namespaces and then detaching otherPkgs a
    #second time through.
    invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE,unload=TRUE))

    bspkgs.nb<-sessionInfo()$basePkgs[sessionInfo()$basePkgs!="base"]
    bspkgs.nbu<-bspkgs.nb[bspkgs.nb!="utils"]
    names(bspkgs.nbu)<-bspkgs.nbu
    suppressMessages(invisible(lapply(paste0('package:', names(bspkgs.nbu)), detach, character.only=TRUE,unload=TRUE)))

    #again this thoroughly removes all packages and loaded namespaces except for base packages "base" and "utils" (which is highly not recommended).

3
ฉันคิดว่าสิ่งนี้สมควรได้รับคะแนนโหวตเนื่องจากความเรียบง่ายและไม่ต้องการแพ็คเกจเพิ่มเติม
Antonio Serrano

สิ่งนี้ไม่ได้ผลสำหรับฉัน ฉันรันมันได้รับคำเตือนจากนั้นรัน session.info () แพ็คเกจทั้งหมดยังอยู่ที่นั่น
dxander

1
ใช่ใน R 3.6.0 เวอร์ชันล่าสุดควรใช้สิ่งต่อไปนี้แทน มองไม่เห็น (lapply (paste0 ('package:', names (sessionInfo () $ otherPkgs)), detach, character.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

59

โปรดลองสิ่งนี้:

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

1
สิ่งนี้ใช้ได้กับ R 4.0.2 ในขณะที่โซลูชันอื่น ๆ ดูเหมือนจะไม่
dss

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 แน่นอน - แต่ฉันไม่ต้องการที่จะเป็นประโยชน์มากเกินไป ;-)
Gavin Simpson

4
คุณอาจต้องการเพิ่มforce=TRUEในกรณีที่แพ็กเกจมีการอ้างอิง
เจมส์

27

nothing

มันอาจจะคุ้มค่าที่จะเพิ่มการแก้ปัญหาทำใช้ได้โดยRomain François เมื่อโหลดแพ็กเกจnothingซึ่งมีอยู่ในGitHubแล้วจะยกเลิกการโหลดแพ็กเกจที่โหลดทั้งหมด ดังตัวอย่างที่ Romain ให้ไว้:

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

การสร้างคำตอบของ Gavin แต่ไม่ใช่ฟังก์ชันเต็มรูปแบบจะเป็นลำดับนี้:

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

3

หรือถ้าคุณมี RStudio ให้ยกเลิกการเลือกช่องทำเครื่องหมายทั้งหมดในแท็บแพ็กเกจเพื่อแยกออก


1
หากคุณมีแพ็กเกจที่โหลดเป็นจำนวนมากการยกเลิกการเลือกทุกแพ็กเกจด้วยตนเองนั้นเป็นเรื่องยุ่งยาก
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()

สิ่งนี้จะทำให้แน่ใจว่าแพ็คเกจทั้งหมดแยกออกจากแพ็คเกจพื้นฐานของคุณ


สิ่งนี้แตกต่างจากคำตอบ
@mjaniec อย่างไร

1

ส่วนใหญ่เป็นปัญหาplyrvs dplyrใช้สิ่งนี้ในจุดเริ่มต้นของรหัส:

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

ดังนั้นเมื่อใดก็ตามที่สคริปต์ทำงานมันจะล้างplyrแพ็คเกจ


0

หากคุณประสบปัญหากับแพ็กเกจที่มีชื่อฟังก์ชันที่คล้ายคลึงกันซึ่งขัดแย้งกันคุณสามารถอ้างอิงเนมสเปซของแพ็กเกจได้ว่าใครเป็นฟังก์ชันที่คุณต้องการ

pkg_name::function_i_want()

นี่คือความคิดเห็นแทนคำตอบสำหรับคำถามที่ถาม
Sibo Jiang

สมมติว่าฉันควรตั้งค่านี้เป็นความคิดเห็นของคำตอบ plyr v. dplyr ก่อนหน้านี้เป็นไปได้ไหมที่จะย้าย ฉันยังคงเรียนรู้การประชุมที่นี่
M. Wood

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)
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.