Why does rm inside a function not delete objects?

后端 未结 2 1010
北海茫月
北海茫月 2020-12-04 02:33
rel.mem <- function(nm) {
  rm(nm)
}

I defined the above function rel.mem -- takes a single argument and passes it to rm

> ls         


        
相关标签:
2条回答
  • 2020-12-04 02:57

    The quick answer is that you're in a different environment - essentially picture the variables in a box: you have a box for the function and one for the Global Environment. You just need to tell rm where to find that box.

    So

    rel_mem <- function(nm) {
       # State the environment
       rm(list=nm, envir = .GlobalEnv )
    }
    x = 10
    rel_mem("x")
    

    Alternatively, you can use the pos argument, e.g.

    rel_mem <- function(nm) {
       rm(list=nm, pos=1 )
    }
    

    If you type search() you will see a vector of environments, the global is number 1.

    Another two options are

    • envir = parent.frame() if you want to go one level up the call stack
    • Use inherits = TRUE to go up the call stack until you find something

    In the above code, notice that I'm passing the object as a character - I'm passing the "x" not x. We can be clever and avoid this using the substitute function

    rel_mem <- function(nm) {
       rm(list = as.character(substitute(nm)), envir = .GlobalEnv )
    }
    

    To finish I'll just add that deleting things in the .GlobalEnv from a function is generally a bad idea.

    Further resources:

    • Environments:http://adv-r.had.co.nz/Environments.html
    • Substitute function: http://adv-r.had.co.nz/Computing-on-the-language.html#capturing-expressions
    0 讨论(0)
  • 2020-12-04 03:06

    If you are using another function to find the global objects within your function such as ls(), you must state the environment in it explicitly too:

    rel_mem <- function(nm) {
       # State the environment in both functions
       rm(list = ls(envir = .GlobalEnv) %>% .[startsWith(., "plot_")], envir = .GlobalEnv)
    }
    
    0 讨论(0)
提交回复
热议问题