Rm(List=Ls()) Doesn't Completely Clear the Workspace

rm(list=ls()) doesn't completely clear the workspace

attach() does not make copies of x and y in your global environment, it attaches a dataframe to the search path.

From ?attach:

The database is not actually attached.  Rather, a new environment
is created on the search path and the elements of a list
(including columns of a data frame) or objects in a save file or
an environment are _copied_ into the new environment. If you use
‘<<-’ or ‘assign’ to assign to an attached database, you only
alter the attached copy, not the original object. (Normal
assignment will place a modified version in the user's workspace:
see the examples.) For this reason ‘attach’ can lead to
confusion.

For example:

> search()
[1] ".GlobalEnv" "package:stats" "package:graphics"
[4] "package:grDevices" "package:utils" "package:datasets"
[7] "package:methods" "Autoloads" "package:base"
> a <- data.frame(stuff=rnorm(100))
> search()
[1] ".GlobalEnv" "package:stats" "package:graphics"
[4] "package:grDevices" "package:utils" "package:datasets"
[7] "package:methods" "Autoloads" "package:base"
> attach(a)
> search()
[1] ".GlobalEnv" "a" "package:stats"
[4] "package:graphics" "package:grDevices" "package:utils"
[7] "package:datasets" "package:methods" "Autoloads"
[10] "package:base"
> rm(list=ls())
> search()
[1] ".GlobalEnv" "a" "package:stats"
[4] "package:graphics" "package:grDevices" "package:utils"
[7] "package:datasets" "package:methods" "Autoloads"
[10] "package:base"
> stuff
[1] -0.91436377 0.67397624 0.62891651 -0.99669584 2.07692590 -0.62702302
[...]
> detach(a)
> search()
[1] ".GlobalEnv" "package:stats" "package:graphics"
[4] "package:grDevices" "package:utils" "package:datasets"
[7] "package:methods" "Autoloads" "package:base"

rm() doesn't seem to empty my R workspace

What you are seeing is the source code for the ls function. When you enter a function name without the parentheses, you'll see the complete source code for that function (provided that function is in one of the packages attached to the search path, or in the global environment).

When you see character(0) as the result of calling ls(), that means that there are no objects in the global environment. The base package, where ls calls home, is different from the global environment, and objects there cannot be removed.

When character(0) is the result of ls() after you call rm(list=ls()), you have successfully cleared the objects in the global environment.

clear everything but one variable rm(list = ls())

Try: rm(list = setdiff(ls(), x))

Edit based on mickey's comment:

Three objects in environment:

ls()
[1] "data_df" "list_ls" "vector_v"

Remove data_df:

rm(list = setdiff(ls(), "data_df"))
ls()
[1] "data_df"

Vector of things to keep:

toKeep_v <- c("list_ls", "vector_v")
rm(list = setdiff(ls(), toKeep_v)
ls()
[1] "list_ls" "vector_v"

rm(list = ls()) doesn't work inside a function. Why?

rm is actually working, however since you're using it inside a function, it only removes all objects pertaining to the environment of that function.

Add envir = .GlobalEnv parameter to both calls:

rm(list = ls(envir = .GlobalEnv), envir = .GlobalEnv)

should do it.

I also recommend you take a look at this other question about gc() as i believe it's not a good practice to call it explicitly unless you really need it.

R: What does `rm(list=ls())` do?

I think the parameter list for the rm function is confusing, at least it was for me when I started using R. The list parameter is not actually supposed to be a list but rather a character vector. The ls-function does return a character vector of all the named objects visible in the environment where it is called and it has a default value that gets used if no other value is offered for its envir argument. If you do this at the console, then the default environment is the global environment. So this will clear all the "visible" objects (but not the ones defined in other namespaces or environments like the ones that exist in the base, graphics, stats or other loaded package-namespaces.

So now go look at ?ls and ?rm to better understand their capabilities. In particular new useRs should get their heads clear on the differences between R names, i.e. symbols, versus the character representations of them. The ls function is really reaching into the language level of R's implementation and returning a non-language-level value, whereas rm typically takes a language level input ... unless (as in this case) it is offered a value to its "list"-argument, ... which is not an R list. Clear? Maybe, hopefully, a bit more so.

Understanding element wise clearing of R's workspace

From ?rm, "Details" section:

Earlier versions of R incorrectly claimed that supplying a character vector in ... removed the objects named in the character vector, but it removed the character vector. Use the list argument to specify objects via a character vector.

Your attempt should have been:

rm(list = WS)

HOWEVER, this will still leave you with an object (a character vector) named "WS" in your workspace since that was created after you called WS <- c(ls()). To actually get rid of the "WS" object, you would have had to use rm(WS, list = WS). :-)


How does it work? If you look at the code for rm, the first few lines of the function captures any individual objects that have been specified, whether quoted or unquoted. Towards the end of the function, you will find the line list <- .Primitive("c")(list, names) which basically creates a character vector of all of the objects individually named and any objects in the character vector supplied to the "list" argument.


Update

Based on your comment, it sounds like you're trying to write a function like:

.clc <- function() {
rm(list = ls(.GlobalEnv), envir = .GlobalEnv)
}

I think it's a little bit of a dangerous function, but let's test it out:

ls()
# character(0)
for (i in 1:5) assign(letters[i], i)
ls()
# [1] "a" "b" "c" "d" "e" "i"
.clc()

ls()
# character(0)

Note: FYI, I've named the function .clc (with a dot) so that it doesn't get removed when the function is run. If you wanted to write a version of the function without the ., you would probably do better to put the function in a package and load that at startup to have the function available.



Related Topics



Leave a reply



Submit