2011-08-24 26 views
6

Estoy intentando escribir una función que elimine un objeto si existe. La razón es que quiero deshacerme del mensaje de registro Error: objeto 'arg' no encontrado. He intentado lo siguiente:Escriba una función para eliminar el objeto si existe

ifrm <- function(arg) 
{ 
    if(exists(as.character(substitute(arg)))){rm(arg)} 
} 

Desafortunadamente esto no quita el objeto si es que existe

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

¿Alguna pista de lo que hago mal?

Mejor Albrecht

+2

Esto suena como una cosa posiblemente peligroso. ¿Quieres darnos un poco más de detalles sobre las circunstancias en las que obtienes este error? Puede haber otras formas de tratar su mensaje de error que sean más apropiadas. – Andrie

+1

Estoy de acuerdo con Andrie. Las respuestas proporcionadas harán lo que usted solicitó, pero lo más probable es que lo que realmente debería hacer sea aún más simple. Eche un vistazo a try y trycatch. ¿Qué es lo que estás tratando de hacer que está tratando de procesar objetos inexistentes? –

Respuesta

8

Un modismo general para captar lo que el usuario proporcionó como argumento para una función es deparse(substitute(foo)). Esta función es similar a la de @Ian Ross pero empleando este lenguaje estándar:

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

donde supongo que sólo alguna vez desea eliminar objetos del entorno global, por lo tanto, el valor por defecto, pero se puede suministrar a través de un entorno env . Y aquí está en acción:

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

Uno debería agregar una advertencia de que el uso de deparse (sustituto()) en una función anidada puede causar problemas. myrm <- function (x) ifrm (x) no hará lo que crees que ... –

+1

@Joris +1 buen punto, pero entonces uno podría decir: ¡no hagas eso! ;-) –

1

Esto es un poco feo, pero parece que funciona:

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

Es posible que desee especificar el entorno de manera diferente si no estás eliminando nombres desde el entorno de alto nivel .

3

Hazlo simple. Simplemente pase el nombre del objeto a su función como una cadena de caracteres, en lugar de tratar de obtener el nombre del objeto real.

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

probar este

a=1; b=3; y=4; ls() 
rm(list = Filter(exists, c("a", "b", "x", "y"))) 
ls() 
Cuestiones relacionadas