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.
Use rm function in function
When you pass rm()
a named object such as val
, it will attempt to remove the object named val
in the specified environment. However, you can use rm()
's "list" option to give it a character vector of names of objects to remove; from help("rm")
:
Arguments
... the objects to be removed, as names (unquoted) or character
strings (quoted).list a character vector naming objects to be
removed.
So, we do this:
rm_wrapper <- function(val, envi){rm(list = val, envir = envi)}
env <- new.env()
assign("v", 3, envir = env)
rm_wrapper("v", env)
ls(env)
# character(0)
We could alternatively make sure the character vectors you're sending your rm()
wrapper are not named objects, like so:
rm_wrapper <- function(..., envi){rm(..., envir = envi)}
env <- new.env()
assign("v", 3, envir = env)
rm_wrapper("v", envi = env)
ls(env)
# character(0)
When is it worth using `remove` in R functions?
From Hadley Wickham's advanced R :
In some languages, you have to explicitly delete unused objects for
their memory to be returned. R uses an alternative approach: garbage
collection (or GC for short). GC automatically releases memory when an
object is no longer used. It does this by tracking how many names
point to each object, and when there are no names pointing to an
object, it deletes that object.
In the case you're describing garbage collection will release the memory.
In case the output of your function is another function, in which case Hadley names these functions respectively the function factory and the manufactured function, the variables created in the body of the function factory will be available in the enclosing environment of the manufactured function, and memory won't be freed.
More info, still in Hadley's book, can be found in the chapter about function factories.
function_factory <- function(x){
force(x)
y <- "bar"
fun <- function(z){
sprintf("x, y, and z are all accessible and their values are '%s', '%s', and '%s'",
x, y, z)
}
fun
}
manufactured_function <- function_factory("foo")
manufactured_function("baz")
#> [1] "x, y, and z are all accessible and their values are 'foo', 'bar', and 'baz'"
Created on 2019-07-08 by the reprex package (v0.3.0)
In this case, if you want to control which variables are available in the enclosing environment, or be sure you don't clutter your memory, you might want to remove unnecessary objects, either by using rm
/ remove
as you did, or as I tend to prefer, wrapped in an on.exit
statement.
Another case in which I might use rm is if I want to access variables from a parent environment without risk of them being overriden inside of the function, but in that case it's often possible and cleaner to use eval.parent
.
y <- 2
z <- 3
test0 <- function(x, var){
y <- 1
x + eval(substitute(var))
}
# opps, the value of y is the one defined in the body
test0(0, y)
#> [1] 1
test0(0, z)
#> [1] 3
# but it will work using eval.parent :
test1 <- function(x, var){
y <- 1
x + eval.parent(substitute(var))
}
test1(0, y)
#> [1] 2
test1(0, z)
#> [1] 3
# in some cases (better avoided), it can be easier/quick and dirty to do something like :
test2 <- function(x, var){
y <- 1
# whatever code using y
rm(y)
x + eval(substitute(var))
}
test2(0, y)
#> [1] 2
test2(0, z)
#> [1] 3
Created on 2019-07-08 by the reprex package (v0.3.0)
R remove objects without throwing an error if they don't exist
Use suppressWarnings
suppressWarnings(rm(a,b,c,d))
Remove multiple objects with rm()
Make the list a character vector (not a vector of names)
rm(list = c('temp1','temp2'))
or
rm(temp1, temp2)
How can I remove all objects but one from the workspace in R?
Here is a simple construct that will do it, by using setdiff
:
rm(list=setdiff(ls(), "x"))
And a full example. Run this at your own risk - it will remove all variables except x
:
x <- 1
y <- 2
z <- 3
ls()
[1] "x" "y" "z"
rm(list=setdiff(ls(), "x"))
ls()
[1] "x"
Delete object after using it in function C++
You would do so by deleting this
within AnObject::Foo
but I would strongly discourage you from doing so. In this case, you do not need pointers at all:
class AnObject{
public:
AnObject Foo(){
return AnObject{};
}
};
int main()
{
AnObject x{};
AnObject result = x.Foo();
return 0;
}
If for whatever reason you really do need pointers, consider smart pointers
#include <memory>
class AnObject{
public:
std::unique_ptr<AnObject> Foo(){
return std::make_unique<AnObject>();
}
};
int main()
{
std::unique_ptr<AnObject> x = std::make_unique<AnObject>();
std::unique_ptr<AnObject> result = x->Foo();
return 0;
}
In both cases, you do not need to delete
anything as you are using RAII semantics to handle your memory cleanup via scope.
Remove objects in .GlobalEnv from within a function
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"
Related Topics
Making Plot Functions with Ggplot and Aes_String
Reading a CSV File Organized Horizontally
R 3.3.0 Installing a Package on Windows: Gcc Not Found Error
R - Faster Way to Calculate Rolling Statistics Over a Variable Interval
How to Manually Change the Key Labels in a Legend in Ggplot2
Asymmetric Expansion of Ggplot Axis Limits
Warning in Install.Packages: Unable to Move Temporary Installation
Convert Accented Characters into Ascii Character
Devtools::Install_Github() - Ignore Ssl Cert Verification Failure
Text-Mining with the Tm-Package - Word Stemming
Configuration Failed Because Libcurl Was Not Found
Dplyr String as Column Reference
Update a Dataset After Putting a New Value in the Dt::Datatable
Finding Euclidean Distance in R{Spatstat} Between Points, Confined by an Irregular Polygon Window
Is There a Fast Estimation of Simple Regression (A Regression Line with Only Intercept and Slope)