2010-10-11 13 views

Odpowiedz

51

Jeśli chcesz użyć konstrukcji try, możesz ustawić opcje ostrzegania. Zobacz także ?options. Lepiej jest użyć 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") 

Aby uzyskać zarówno wynik i ostrzeżenie:

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

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

Korzystanie try

op <- options(warn=2) 

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

dzięki za zmianę, pokazującą, jak uzyskać zarówno wynik, jak i ostrzeżenie; jednak funkcja jest wywoływana dwukrotnie, gdy pojawi się ostrzeżenie. Czy można to zrobić za pomocą tylko jednego połączenia (na przykład w przypadku, gdy funkcja jest wolna)? – Aaron

+0

@Aaron: wtedy wybrałbym obsługę, jak pokazano poniżej. To najczystszy sposób, a te są do tego stworzone. To wymaga nieco więcej zagadek. –

+0

Dzięki. To jest zdecydowanie zagadkowe. Chociaż robi to, czego potrzebuję, w tym kodzie jest dużo, czego jeszcze nie rozumiem. – Aaron

4

Oto przykład:

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") 
} 

może to jest jakiś sposób pośredni, ale nie wiem, bardziej bezpośredni sposób.

+0

Chociaż jest to nieeleganckie, jest dobre, ponieważ nie mogę znaleźć żadnego innego sposobu na ostrzeżenie, a mimo to zwróć normalny wynik z funkcji. Oznacza to, że jeśli testit() zwróci wartość, wychwycenie ostrzeżenia za pomocą tryExcept oznacza utratę wartości. Chyba że czegoś mi brakuje? –

+1

@Alex: można zrobić całkiem łatwo za pomocą formuły tryCatch. Możesz zrobić coś z ostrzeżeniem w argumencie, np .: warning = function (w) {... zrób coś ... return (normalny wynik)} –

+0

@Joris: Nie mogłem uzyskać funkcji tryCatch, która zwróci normalny wynik. Czy czegoś brakuje? Znalazłem sposób używania z CallingHandlers z listy mailingowej R (dołączonej jako osobna odpowiedź). – Aaron

18

na liście mailingowej R-pomocy (patrz http://tolstoy.newcastle.edu.au/R/help/04/06/0217.html) Luke Tierney napisał:

"Jeśli chcesz napisać fu nction który oblicza wartość i zbiera wszystkie ostrzegawczy można zrobić to tak:?

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

to "<< -" poprawne? – isomorphismes

+4

Tak, to aktualizuje 'myWarnings' poza funkcją; w przeciwnym razie tworzy nowe 'myWarnings' w funkcji, a na zewnątrz nie jest aktualizowane. – Aaron

Powiązane problemy