127

While working to solve another problem I got this problem:

I can remove all R objects by:

rm(list = ls(all = TRUE))

Is there equivalent command that can detach installed packages during working session?

> 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 

I tried this way, although even it worked in not a global solution :

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

What I am loking for is something global like:

  rm(list = ls(all = TRUE))

for objects, expect it would not remove attached base packages

thanks;

Konrad
  • 17,740
  • 16
  • 106
  • 167
John Clark
  • 2,639
  • 5
  • 19
  • 13
  • 4
    Not that your question isn't valid, but why not just restart R? – Aaron left Stack Overflow Sep 21 '11 at 19:39
  • 5
    @Aaron because you shouldn't have too ;-) To pass `R CMD check` a package is supposed to cleanly unload itself, so R Core expect this to be possible and something one might wish to do. – Gavin Simpson Sep 21 '11 at 19:52
  • @Aaron, I think sometime it might be useful to let session going when some packages are causing or might cause interference, but were used in previous steps ... – John Clark Sep 21 '11 at 22:10
  • 7
    It's not possible to return R to a fresh slate. I've talked with John Chambers about this, and it's particularly difficult to do for S4 class/method registration. – hadley Sep 26 '11 at 20:24

11 Answers11

126

So, someone should have simply answered the following.

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

(edit: 6-28-19) In the latest version of R 3.6.0 please use instead.

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

Note the use of invisible(*) is not necessary but can be useful to prevent the NULL reply from vertically spamming the R window.

(edit: 9/20/2019) In version 3.6.1

It may be helpful to convert loaded only names(sessionInfo()$loadedOnly) to explicitly attached packages first, and then detach the packages, as so.

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

One can attempt to unload base packages via $basePkgs and also attempt using unloadNamespace(loadedNamespaces()). However these typically are fraught with errors and could break basic functionality such as causing sessionInfo() to return only errors. This typically occurs because of a lack of reversibility in the original package's design. Currently timeDate can break irreversibly, for example.

(edit: 9/24/20) for version 4.0.2 The following first loads packages to test and then gives a sequence to fully detach all packages except for package "base" and "utils". It is highly recommended that one does not detach those packages.

    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).
mmfrgmpds
  • 1,308
  • 1
  • 8
  • 14
  • 3
    I think this deserves upvotes because of its simplicity and does not need additional packages. – Antonio Serrano Apr 12 '18 at 11:32
  • This did not work for me. I ran it got warnings, then ran session.info() all packages were still there. – dxander Jun 27 '19 at 00:51
  • 1
    Yes in the latest version of R 3.6.0 one should use the following instead. invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE)) Note the use of invisible(*) is not required but can prevent the NULL reply from vertically spamming the window. – mmfrgmpds Jun 28 '19 at 18:20
  • Using ```invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only=TRUE, unload=TRUE))``` results in an ```Error in FUN(X[[i]], ...) : invalid 'name' argument``` error – dvanic Sep 19 '19 at 03:46
  • The error `Error in FUN(X[[i]], ...)...` frequently occurs when there is only a NULL value present. One can test for this with `names(sessionInfo()$otherPkgs)`. If it returns `NULL`, then this is the cause. – mmfrgmpds Sep 20 '19 at 16:31
  • It should work now and detach even more packages. The issue seemed to be the weird protection added to `sessionInfo()$basePkgs` Even though this tests correct with all expected attributes, typeof's, classes, and object type, it seems to be highly protected and refuses to be parsed normally. Additionally, it seems the function of the operation `names` has been changed significantly, and is much more restrictive inexplicably. – mmfrgmpds Sep 24 '20 at 16:31
  • @mmfrgmpds, This is not working at all with R version 4.1.0 (2021-05-18). – Krantz Jan 15 '23 at 14:21
  • @Krantz, This seems to be an anomalous behavior in 4.1.0. I have confirmed that the functionality has returned in version 4.2.1 and version 4.2.2 (current version of R). – mmfrgmpds Jan 17 '23 at 14:03
62

Please try this:

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,074
  • 1
  • 9
  • 12
30

nothing

It may be worth to add solution made available by Romain François. When loaded the package nothing, which is currently available on GitHub, will unload all of the loaded packages; as in the example that Romain provides:

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

require(nothing, quietly = TRUE)

loadedNamespaces()
[1] "base"

Installation

With use of the devtools package:

devtools::install_github("romainfrancois/nothing")

pacman

An alternative approach uses pacman package available through CRAN:

pacman::p_unload(pacman::p_loaded(), character.only = TRUE)
Konrad
  • 17,740
  • 16
  • 106
  • 167
  • 5
    Looking at the vignette (http://trinker.github.io/pacman/vignettes/Introduction_to_pacman.html) maybe `pacman::p_unload("all")` would work as well? – chandler Jul 22 '17 at 18:58
  • 'nothing' could actually be a really useful little package, but it removes 'utils' and then crashes RStudio if you try to reload it. – vorpal Feb 25 '22 at 04:54
  • @vorpal The OP didn't mention anything about working in RStudio, naturally if you happen to be working with R using RStudio, VSCode, Nvim-R or any other setup you may be willing to keep the required packages loaded. Other answers provide ways of achieving that. BTW, I reckon that RStudio may need some other packages to be loaded so it can function properly; like `rstudioapi` and whatever is required to support the add-ins mechanism. – Konrad Feb 25 '22 at 14:50
  • pacman did not work for me, but sure `require(nothing, quietly = TRUE)` worked! thanks. – LeMarque Sep 01 '22 at 11:56
28

You were close. Note what ?detach has to say about the first argument name of detach():

Arguments:

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

So we need to repeatedly call detach() once per element of pkg. There are a couple of other arguments we need to specify to get this to work. The first is character.only = TRUE, which allows the function to assume that name is a character string - it won't work without it. Second, we also probably want to unload any associated namespace. This can be achieved by setting unload = TRUE. So the solution is, for example:

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

Here is a full example:

> 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

If you want to turn this into a function, study the code in sessionInfo() to see how it identifies what it labels as "other attached packages:". Combine that bit of code with the idea above in a single function and you are home and dry. I'll leave that bit up to you though.

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
9

Building on Gavin's answer but not quite to a full function would be this sequence:

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
  • 258,963
  • 21
  • 364
  • 487
  • 2
    somehow I can do the same with a one-liner `lapply(paste("package:", names(sessionInfo()$otherPkgs), sep=""), detach, character.only = TRUE, unload = TRUE)`. Would never get there without your answer though! – Ufos Feb 22 '18 at 11:32
4

or if you have RStudio, simply uncheck all the checked boxes in Packages Tab to detach

Ajay Ohri
  • 3,382
  • 3
  • 30
  • 60
  • 2
    If you have a lot of loaded packages, it is cumbersome to uncheck every one manually. – SJ9 Mar 22 '19 at 19:43
4
#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()

this will make sure all packages gets detached apart from your basic packages

StupidWolf
  • 45,075
  • 17
  • 40
  • 72
jazzie
  • 41
  • 2
3

Most of the times its the plyr vs dplyr issue. Use this in the beginning of the code:

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

So whenever the script runs, its clears the plyr package

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Prashant
  • 39
  • 1
0

Combining bits from various answers gave the most robust solution I could find...

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
  • 481
  • 4
  • 16
0

Why not the below to remove all attached packages ?

intialPackages = search() # added as 1st line of R script to get list of default packages
# below lines are added when newly attached packages needs to be removed
newPackages = search()[!(search() %in% intialPackages)]
try(sapply(newPackages, detach, character.only=TRUE, unload=TRUE, force=TRUE), silent=TRUE)
Ajay
  • 87
  • 4
-1

if you're having problems with packages that have similarly named functions conflicting with each other, you can always reference the namespace of the package who's function you DO want.

pkg_name::function_i_want()
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
M. Wood
  • 450
  • 4
  • 13
  • This is comment instead of an answer to the asked question. – SJ9 Mar 23 '19 at 06:03
  • Suppose I ought have set this as comment to the previous plyr v. dplyr answer, is it possible to move it? I am still learning the conventions here. – M. Wood Mar 25 '19 at 20:01