Reputation: 509
I am trying to write a function that removes an object if it exists. The reason is that I want to get rid of the log-message Error: object 'arg' not found. I tried the following:
ifrm <- function(arg)
{
if(exists(as.character(substitute(arg)))){rm(arg)}
}
Unfortunately this does not remove the object if it exists
> ifrm <- function(arg)
+ {
+ if(exists(as.character(substitute(arg)))){rm(arg)}
+ }
> a <- 2
> ifrm(a)
> a
[1] 2
Any hints what I do wrong here?
Best Albrecht
Upvotes: 7
Views: 8214
Reputation: 77096
Try this
a=1; b=3; y=4; ls()
rm( list = Filter( exists, c("a", "b", "x", "y") ) )
ls()
Upvotes: 7
Reputation: 121057
Keep it simple. Just pass the name of the object into your function as a character string, rather than trying to get the name from the actual object.
ifrm <- function(x, env = globalenv())
{
if(exists(x, envir = env))
{
rm(list = x, envir = env)
}
}
Upvotes: 4
Reputation: 174788
A general idiom to grab what the user supplied as an argument to a function is deparse(substitute(foo))
. This function is similar to that of @Ian Ross but employing this standard idiom:
ifrm <- function(obj, env = globalenv()) {
obj <- deparse(substitute(obj))
if(exists(obj, envir = env)) {
rm(list = obj, envir = env)
}
}
where I assume you only ever want to remove objects from the global environment, hence the default, but you can supply an environment via env
. And here it is in action:
> a <- 1:10
> ls()
[1] "a" "ifrm"
> ifrm(a)
> ls()
[1] "ifrm"
> ifrm(a)
> ls()
[1] "ifrm"
Upvotes: 10
Reputation: 987
This is kind of ugly, but it seems to work:
ifrm <- function(arg) {
if (exists(as.character(substitute(arg)))) {
rm(list=as.character(substitute(arg)), envir=sys.frame())
}
}
You might want to specify the environment differently if you're not removing names from the top-level environment.
Upvotes: 3