10

First of all, this question has a similar title, but there the environment only seemed to be unclean. Until now I thought that after

rm(list=ls(globalenv()))

we had a global environment as clean as it was when R was started for the first time. But by accident I realized that at least the class definitions survive:

rm(list=ls(globalenv()),envir=globalenv())
sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})

ls(globalenv())
getClasses(globalenv())

#----------------------------------------------------------------
x <- 1:3
setClass("A", where=globalenv())

ls(globalenv())
getClasses(globalenv())

#----------------------------------------------------------------
rm(list=ls(globalenv()),envir=globalenv())
ls(globalenv())
getClasses(globalenv())

#----------------------------------------------------------------
sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})
ls(globalenv())
getClasses(globalenv())

Warning: After running this reproducable example your global environment will be cleaner than after "rm(list=ls())".

> source('~/.active-rstudio-document', echo=TRUE)

> rm(list=ls(globalenv()),envir=globalenv())

> sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})
named list()

> ls(globalenv())
character(0)

> getClasses(globalenv())
character(0)

> #----------------------------------------------------------------
> x <- 1:3

> setClass("A", where=globalenv())

> ls(globalenv())
[1] "x"

> getClasses(globalenv())
[1] "A"

> #----------------------------------------------------------------
> rm(list=ls(globalenv()),envir=globalenv())

> ls(globalenv())
character(0)

> getClasses(globalenv())
[1] "A"

> #----------------------------------------------------------------
> sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})
   A 
TRUE 

> ls(globalenv())
character(0)

> getClasses(globalenv())
character(0)
> 

At least I understand now why in the documentation of "rm" it says that

rm(list = ls())

will remove (almost) everything in the working environment.

First I thought that only "ls" was the bad guy, since it doesn't tell "rm" the names of the classes. But "rm" discounts the class names:

rm(list=ls(globalenv()),envir=globalenv())
sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})

ls(globalenv())
getClasses(globalenv())

#----------------------------------------------------------------
x <- 1:3
setClass ( "A", where=globalenv() )

ls(globalenv())
getClasses(globalenv())

#----------------------------------------------------------------
rm(list=ls(globalenv()),envir=globalenv())
rm(list=getClasses(globalenv()),envir=globalenv())

ls(globalenv())
getClasses(globalenv())

.

> source('~/.active-rstudio-document', echo=TRUE)

> rm(list=ls(globalenv()),envir=globalenv())

> sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})
named list()

> ls(globalenv())
character(0)

> getClasses(globalenv())
character(0)

> #----------------------------------------------------------------
> x <- 1:3

> setClass ( "A", where=globalenv() )

> ls(globalenv())
[1] "x"

> getClasses(globalenv())
[1] "A"

> #----------------------------------------------------------------
> rm(list=ls(globalenv()),envir=globalenv())

> rm(list=getClasses(globalenv()),envir=globalenv())

> ls(globalenv())
character(0)

> getClasses(globalenv())
[1] "A"
Warning message:
In rm(list = getClasses(globalenv()), envir = globalenv()) :
  object 'A' not found
> 

Due to this warning I guess that

  • R does not count class definitions among "Objects", and
  • "rm" removes nothing but "Objects".

So it seems that "rm" is not able to remove everything. At least the deletion of class definitions requires some additional work. This scares me that there might be something else but objects and class definitions still hiding in the environment, even after "rm" and "removeClass" have done their damnedest.

Is there a command that clears out an environment completely, bar none?

Community
  • 1
  • 1
mra68
  • 2,960
  • 1
  • 10
  • 17
  • 3
    `rm(list = ls(all.names = TRUE))`? – nrussell Aug 17 '15 at 12:24
  • 1
    Ok. So the reason is that the name of the class A is ".__C__A", not "A". – mra68 Aug 17 '15 at 12:30
  • 4
    @nrussell That’s necessary but not sufficient. Some class information (notably for S3, I have no idea about S4 as I don’t use it) is saved in namespace attributes, not in the global namespace. – Konrad Rudolph Aug 17 '15 at 12:31
  • @KonradRudolph Fair enough - the only "test" I put that to was the OP's `getClasses(globalenv())` test - which returns `character(0)` (tested on the first example in the `?setClass` helpfile). – nrussell Aug 17 '15 at 12:33
  • 1
    @mra68 Well, not exactly. The name of the class *is* `A`, but `.__C__A` is more like meta data associated with the class. If you do `str(.__C__A)` you will get, among other output, `Formal class 'classRepresentation' ...`, with one of the slots being `@ className : atomic [1:1] A`. – nrussell Aug 17 '15 at 12:38

1 Answers1

1

The best option is to restart r. I've seen it recommended by experienced r programmers who also recommend avoiding rm(list = ls()) because "it makes your script vulnerable to hidden dependencies on things you ran" prior to it but in that same process. https://www.tidyverse.org/articles/2017/12/workflow-vs-script/

n.soto
  • 11
  • 2
  • In RStudio, menu command "Restart R" does not clean workspace, but menu command "Clean workspace..." cleans it. – Heikki Sep 28 '18 at 20:06