Jak napisać trycatch w R

Chcę napisać trycatch kod, aby poradzić sobie z błędem w pobieraniu z sieci.

url <- c(
    "http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html",
    "http://en.wikipedia.org/wiki/Xz")
y <- mapply(readLines, con=url)

Te dwa stwierdzenia działają pomyślnie. Poniżej tworzę nieistniejący adres www:

url <- c("xxxxx", "http://en.wikipedia.org/wiki/Xz")

url[1] nie istnieje. Jak napisać trycatch pętlę (funkcję) tak, że:

  1. gdy URL jest nieprawidłowy, wyjście będzie brzmiało: "web URL is wrong, can 't get".
  2. Gdy adres URL jest nieprawidłowy, kod nie zatrzymuje się, ale kontynuuje pobieranie do końca listy Url?
Author: smci, 2012-08-30

4 answers

No to Witamy w świecie R; -)

Proszę bardzo

Ustawianie kodu

urls <- c(
    "http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html",
    "http://en.wikipedia.org/wiki/Xz",
    "xxxxx"
)
readUrl <- function(url) {
    out <- tryCatch(
        {
            # Just to highlight: if you want to use more than one 
            # R expression in the "try" part then you'll have to 
            # use curly brackets.
            # 'tryCatch()' will return the last evaluated expression 
            # in case the "try" part was completed successfully

            message("This is the 'try' part")

            readLines(con=url, warn=FALSE) 
            # The return value of `readLines()` is the actual value 
            # that will be returned in case there is no condition 
            # (e.g. warning or error). 
            # You don't need to state the return value via `return()` as code 
            # in the "try" part is not wrapped insided a function (unlike that
            # for the condition handlers for warnings and error below)
        },
        error=function(cond) {
            message(paste("URL does not seem to exist:", url))
            message("Here's the original error message:")
            message(cond)
            # Choose a return value in case of error
            return(NA)
        },
        warning=function(cond) {
            message(paste("URL caused a warning:", url))
            message("Here's the original warning message:")
            message(cond)
            # Choose a return value in case of warning
            return(NULL)
        },
        finally={
        # NOTE:
        # Here goes everything that should be executed at the end,
        # regardless of success or error.
        # If you want more than one expression to be executed, then you 
        # need to wrap them in curly brackets ({...}); otherwise you could
        # just have written 'finally=<expression>' 
            message(paste("Processed URL:", url))
            message("Some other message at the end")
        }
    )    
    return(out)
}

Stosowanie kodu

> y <- lapply(urls, readUrl)
Processed URL: http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html
Some other message at the end
Processed URL: http://en.wikipedia.org/wiki/Xz
Some other message at the end
URL does not seem to exist: xxxxx
Here's the original error message:
cannot open the connection
Processed URL: xxxxx
Some other message at the end
Warning message:
In file(con, "r") : cannot open file 'xxxxx': No such file or directory

Badanie wyjścia

> head(y[[1]])
[1] "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"      
[2] "<html><head><title>R: Functions to Manipulate Connections</title>"      
[3] "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
[4] "<link rel=\"stylesheet\" type=\"text/css\" href=\"R.css\">"             
[5] "</head><body>"                                                          
[6] ""    

> length(y)
[1] 3

> y[[3]]
[1] NA

Uwagi dodatkowe

TryCatch

tryCatch Zwraca wartość związaną z wykonaniem expr, chyba że wystąpił błąd lub ostrzeżenie. W tym przypadku konkretne wartości zwracane (patrz return(NA) powyżej) mogą być określone przez podanie odpowiedniej funkcji obsługi (patrz argumenty error i warning w ?tryCatch). Mogą to być funkcje, które już istnieją, ale można je również zdefiniować w tryCatch() (Jak to zrobiłem powyżej).

Implikacje wyboru konkretnych wartości zwracanych przez funkcje obsługi

Jak określiliśmy, że NA powinno być zwracane w przypadku błędu, trzecim elementem y jest NA. Jeśli wybralibyśmy NULL jako wartość zwracaną, długość y byłaby po prostu 2 zamiast 3, ponieważ lapply() będzie po prostu "ignoruj" zwraca wartości NULL. Zauważ również, że jeśli nie podasz jawnej wartości zwracanej przez return(), funkcje obsługi zwrócą NULL (tzn. w przypadku błędu lub warunku Ostrzeżenia).

"niechciane" Ostrzeżenie

W przeciwieństwie do poprzednich wersji gry, nie jest to możliwe w przypadku, gdy nie jest to możliwe.]}
suppressWarnings(readLines(con=url))

Zamiast

readLines(con=url, warn=FALSE)

Wielokrotne wyrażenia

Zauważ, że możesz również umieścić wiele wyrażeń w "części wyrażeń rzeczywistych" (argument expr z tryCatch()), jeśli zawiń je w nawiasy klamrowe(tak jak zilustrowałem w części finally).

 444
Author: Rappster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-11 17:12:21

R wykorzystuje funkcje do implementacji bloku try-catch:

Składnia wygląda nieco tak:

result = tryCatch({
    expr
}, warning = function(warning_condition) {
    warning-handler-code
}, error = function(error_condition) {
    error-handler-code
}, finally={
    cleanup-code
})

W tryCatch() są dwa "warunki", które mogą być obsługiwane: "ostrzeżenia" i "błędy". Ważną rzeczą do zrozumienia podczas pisania każdego bloku kodu jest stan wykonania i zakres. @ source

 52
Author: heretolearn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-28 11:19:39

Oto prosty przykład :

# Do something, or tell me why it failed
my_update_function <- function(x){
    tryCatch(
        # This is what I want to do:
        y = x * 2
        return(y)
        ,
        # ... but if an error occurs, tell me what happened: 
        error=function(error_message) {
            message("My message is here!")
            message("And below is the error message from R:")
            message(error_message)
            return(NA)
        }
    )
}

Jeśli chcesz również uchwycić "Ostrzeżenie", po prostu dodaj warning= podobne do części error=.

 18
Author: Paul Paczuski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 21:57:27

Ponieważ właśnie straciłem dwa dni mojego życia próbując rozwiązać tryCatch dla funkcji irr, pomyślałem, że powinienem podzielić się moją mądrością (i tym, czego brakuje). FYI-irr jest rzeczywistą funkcją z FinCal w tym przypadku, gdzie dostał błędy w kilku przypadkach na dużym zbiorze danych.

  1. Ustaw tryCatch jako część funkcji. Na przykład:

    irr2 <- function (x) {
      out <- tryCatch(irr(x), error = function(e) NULL)
      return(out)
    }
    
  2. Aby błąd (lub ostrzeżenie) zadziałał, musisz utworzyć funkcję. I pierwotnie dla error part just wrote error = return(NULL) and ALL wartości wróciły null.

  3. Pamiętaj, aby utworzyć wyjście podrzędne (jak moje "out") i return(out).

 16
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-26 10:47:08