2010-10-11 7 views

Respuesta

51

Si desea utilizar las construcciones try, puede establecer las opciones para advertir. Consulte también ?options. Mejor es utilizar tryCatch():

x <- function(i){ 
    if (i < 10) warning("A warning") 
    i 
} 

tt <- tryCatch(x(5),error=function(e) e, warning=function(w) w) 

tt2 <- tryCatch(x(15),error=function(e) e, warning=function(w) w) 

tt 
## <simpleWarning in x(5): A warning> 

tt2 
## [1] 15 

if(is(tt,"warning")) print("KOOKOO") 
## [1] "KOOKOO" 

if(is(tt2,"warning")) print("KOOKOO") 

Para obtener el resultado y la advertencia:

tryCatch(x(5),warning=function(w) return(list(x(5),w))) 

## [[1]] 
## [1] 5 
## 
## [[2]] 
## <simpleWarning in x(5): A warning> 

Usando try

op <- options(warn=2) 

tt <- try(x()) 
ifelse(is(tt,"try-error"),"There was a warning or an error","OK") 
options(op) 
+3

gracias por su edición que muestra cómo obtener el resultado y la advertencia; sin embargo, la función se llama dos veces cuando hay una advertencia. ¿Se puede hacer con una sola llamada (en caso de que la función sea lenta, por ejemplo)? – Aaron

+0

@ Aaron: entonces iré por los controladores como se muestra a continuación por usted. Esa es la manera más limpia, y esos están hechos para hacer eso. Solo requiere un poco más de desconcierto. –

+0

Gracias. Definitivamente es desconcertante. Aunque hace lo que necesito, hay mucho en ese código que todavía no entiendo. – Aaron

4

aquí es un ejemplo:

testit <- function() warning("testit") # function that generates warning. 

assign("last.warning", NULL, envir = baseenv()) # clear the previous warning 

testit() # run it 

if(length(warnings())>0){ # or !is.null(warnings()) 
    print("something happened") 
} 

tal vez esto es de alguna manera indirecta, pero no saben la manera más sencilla.

+0

Aunque esto no es elegante, es bueno porque no puedo encontrar ninguna otra forma de detectar una advertencia y, sin embargo, devuelvo el resultado normal de la función. Es decir, si testit() devuelve un valor, capturar una advertencia con tryExcept significa que pierde el valor. A menos que me esté perdiendo algo? –

+1

@Alex: puedes hacerlo bastante fácilmente usando una fórmula tryCatch. Puede hacer algo con la advertencia en el argumento, por ejemplo: warning = function (w) {... hacer algo ... return (resultado normal)} –

+0

@Joris: No pude hacer que tryCatch devolviera el resultado normal. ¿Me estoy perdiendo de algo? Encontré una forma de usar withCallingHandlers, de la lista de correo R (incluida como una respuesta separada). – Aaron

18

En la lista de correo R-ayuda (ver http://tolstoy.newcastle.edu.au/R/help/04/06/0217.html), Luke Tierney escribió:

"Si quieres escribir un fu nción que calcula un valor y reúne toda la advirtiendo que podría hacerlo de esta manera:?

withWarnings <- function(expr) { 
    myWarnings <- NULL 
    wHandler <- function(w) { 
     myWarnings <<- c(myWarnings, list(w)) 
     invokeRestart("muffleWarning") 
    } 
    val <- withCallingHandlers(expr, warning = wHandler) 
    list(value = val, warnings = myWarnings) 
} 
+1

es '<< -' correcto? – isomorphismes

+4

Sí, de esa manera actualiza 'myWarnings' fuera de la función; de lo contrario, crea un nuevo 'myWarnings' dentro de la función y el exterior no se actualiza. – Aaron

Cuestiones relacionadas