16

I would like to create a function (CleanEnvir) which basically calls remove/rm and which removes certain objects from .GlobalEnv.

  CleanEnvir <- function(pattern = "tmp"){
      rm(list = ls()[grep("tmp", ls())], envir = globalenv())
  }

  keep <- 1
  tmp.to.be.removed <- 0
  ls()

  ## does not work
  CleanEnvir()
  ls()

  ## does work
  rm(list = ls()[grep("tmp", ls())], envir = globalenv())
  ls()
Bernd Weiss
  • 927
  • 1
  • 14
  • 24

3 Answers3

22

ls() needs to look in the correct place. By default it looks in the current frame, that of the function CleanEnvir in your case and hence was only finding "pattern" in your original.

CleanEnvir <- function(pattern = "tmp") {
    objs <- ls(pos = ".GlobalEnv")
    rm(list = objs[grep("tmp", objs)], pos = ".GlobalEnv")
}

Which gives:

> CleanEnvir <- function(pattern = "tmp") {
+     objs <- ls(pos = ".GlobalEnv")
+     rm(list = objs[grep("tmp", objs)], pos = ".GlobalEnv")
+ }
> ls()
[1] "CleanEnvir"        "foo"               "keep"             
[4] "tmp.to.be.removed"
> CleanEnvir()
> ls()
[1] "CleanEnvir" "foo"        "keep"
Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
9

You need to do your search in the Global Env as well as the removal there:

CleanEnvir <- function(pattern = "tmp"){
      rm(list = ls(envir=globalenv())[
             grep("tmp", ls(envir=globalenv()))], envir = globalenv())
  }
IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • Thanks! I never considered the ls()-part as being problematic. BTW, the second ls() in grep() also needs to be replaced by ls(envir=globalenv()). – Bernd Weiss Jan 29 '11 at 15:31
  • OK. Sounds right, so added, but it seemed to work when I tested it earlier. – IRTFM Jan 29 '11 at 21:13
3

Shortest code solution I got for this is this one:

remove a specific variable:

y <- TRUE

CleanEnvir <- function(x) {rm(list=deparse(substitute(x)),envir=.GlobalEnv)}

CleanEnvir(y)
y

deparse substitute to paste the variable name rather than its value, and indeed pos = ".GlobalEnv" works, but you can also simply use envir=.GlobalEnv

SOLUTION 2: This actually allows for pattern matching. (I STRONGLY recommend against this because you could possibly remove stuff you don't want to remove by accident. I.e. you want to remove tmp1 and tmp2 but you forgot that there is another variable that is called Global.tmp and localtmp as in temperature for example.

remove by pattern:

myvar1 <- TRUE
myvar2 <- FALSE 

Pat.clean.Envir <- function(x) { rm(list = ls(.GlobalEnv)[grep(deparse(substitute(x)), ls(.GlobalEnv))], envir = .GlobalEnv) }

Pat.clean.Envir(myvar)

cheers.

Mark
  • 2,789
  • 1
  • 26
  • 66
  • This *is* shorter than the other answers, but does not allow partial matching of arguments as suggested in the OP. – BenBarnes May 31 '17 at 09:40
  • Ok I edited a solution that does that. However, the user never asked for pattern matching in the title or the descriptive quesiton. Only in his code there is an approach that involves pattern Matching. As explained in my answer, I strongly recommend against partial pattern machting though because if you do it wrong, you'll remove the wrong variable. Run it for fun with pattern of 1 letter: "a" by accident, and 80% of your variables are gone. – Mark May 31 '17 at 12:39