编写一个函数,如果对象存在则删除它。

7
我正在尝试编写一个函数,以删除指定对象。这是因为我想摆脱“Error: object 'arg' not found”的日志信息。我尝试了以下代码:
ifrm <- function(arg)
{
   if(exists(as.character(substitute(arg)))){rm(arg)}
}

很遗憾,如果对象已存在,这不会将其删除。

> ifrm <- function(arg)
+ {
+    if(exists(as.character(substitute(arg)))){rm(arg)}
+ }
> a <- 2
> ifrm(a)
> a
[1] 2

有什么提示可以告诉我在这里做错了什么吗?

最好的阿尔布雷希特


2
这听起来可能是一件危险的事情。你能否给我们更多关于出现错误的情况细节?也许有其他更合适的处理错误信息的方法。 - Andrie
2
我同意Andrie的观点。提供的答案可以完成你所要求的任务,但实际上你应该做的可能更简单。看一下try和trycatch。你试图处理不存在的对象是什么? - Carl Witthoft
4个回答

10

一个常用的获取用户提供给函数参数的习惯用法是deparse(substitute(foo))。这个函数类似于@Ian Ross的函数,但使用这个标准用法:

ifrm <- function(obj, env = globalenv()) {
    obj <- deparse(substitute(obj))
    if(exists(obj, envir = env)) {
        rm(list = obj, envir = env)
    }
}

我假定您只想从全局环境中删除对象,因此使用默认值,但是您可以通过 env 提供一个环境。以下是实际操作:

> a <- 1:10
> ls()
[1] "a"    "ifrm"
> ifrm(a)
> ls()
[1] "ifrm"
> ifrm(a)
> ls()
[1] "ifrm"

2
应该加上警告,使用deparse(substitute())在嵌套函数中会导致麻烦。myrm <- function(x) ifrm(x)不会像你想的那样运行... - Joris Meys
2
@Joris +1 好观点,但也可以说,不要那样做!;-) - Gavin Simpson

7
尝试这个。
 a=1; b=3; y=4; ls() 
 rm( list = Filter( exists, c("a", "b", "x", "y") ) )
 ls()

4

保持简单。只需将对象的名称作为字符串传递到您的函数中,而不是尝试从实际对象获取名称。

ifrm <- function(x, env = globalenv()) 
{
  if(exists(x, envir = env)) 
  {
    rm(list = x, envir = env)
  }
}

3

这看起来有点丑陋,但似乎可以工作:

ifrm <- function(arg) {
  if (exists(as.character(substitute(arg)))) {
    rm(list=as.character(substitute(arg)), envir=sys.frame())
  }
}

如果您不从顶层环境中删除名称,则可能需要以不同的方式指定环境。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接