Przechwytywanie błędów za pomocą tryCatch()
Część sekcji Logika i przepływ sterowania ścieżki R w Coddy. Lekcja 53 z 64.
tryCatch(expr, error = function(e) ...) uruchamia expr. Jeśli wystąpi błąd, zamiast niego uruchamiana jest procedura obsługi, a jej wartość staje się wynikiem; skrypt działa dalej:
safe_sqrt <- function(x) {
tryCatch(sqrt(x), error = function(e) NA)
}
print(safe_sqrt(16))
print(safe_sqrt("a"))
print("still running")Wynik:
[1] 4
[1] NA
[1] "still running"Procedura obsługi otrzymuje błąd jako e, a conditionMessage(e) zwraca jego treść:
result <- tryCatch(
stop("file not found"),
error = function(e) paste("Problem:", conditionMessage(e))
)
print(result)Wynik:
[1] "Problem: file not found"Opakuj tylko wywołanie, które może się nie powieść, i obsłuż błąd tam, gdzie możesz zrobić coś użytecznego, na przykład zwrócić wartość domyślną lub wyświetlić komunikat użytkownikowi:
to_number <- function(s) {
tryCatch({
if (s == "") stop("empty input")
as.integer(s)
}, error = function(e) -1L)
}
print(to_number("42"))
print(to_number(""))Wynik:
[1] 42
[1] -1W pętli tryCatch() pozwala, aby jeden nieprawidłowy element spowodował błąd, podczas gdy pozostałe są nadal przetwarzane:
inputs <- list(4, "x", 9)
for (v in inputs) {
r <- tryCatch(sqrt(v), error = function(e) "not a number")
cat(format(v), "->", r, "\n")
}Wynik:
4 -> 2
x -> not a number
9 -> 3 Wyzwanie
ŁatwyUzupełnij safe_divide(a, b). Użyj tryCatch(): wewnątrz zgłoś błąd division by zero, gdy b wynosi 0, a w przeciwnym razie oblicz a / b. Obsługa błędu zwraca Error: , po którym następuje komunikat. Zwróć wynik zaokrąglony do dwóch miejsc po przecinku jako tekst, 3.33, albo tekst błędu.
Dostarczony kod odczytuje pary liczb, takie jak 10/3, oddzielone przecinkami, i wypisuje wynik każdej pary w osobnym wierszu.
Spróbuj swoich sił
safe_divide <- function(a, b) {
# Wpisz tutaj swój kod
""
}
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
input <- suppressWarnings(readLines(file("stdin")))
for (pair in strsplit(input[1], ",")[[1]]) {
p <- as.numeric(strsplit(pair, "/")[[1]])
cat(safe_divide(p[1], p[2]), "\n", sep = "")
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Logika i przepływ sterowania
1Łańcuchy znaków w szczegółach
Podciągi za pomocą substr()Formatowanie za pomocą sprintf()Dzielenie i łączenieWyszukiwanie w łańcuchach znakówZastępowanie tekstuPowtórka – kreator nazwy użytkownika4Macierze
Tworzenie macierzyIndeksowanie macierzyPodsumowania wierszy i kolumnDziałania na macierzachPowtórka – plan miejsc10Zaawansowane sterowanie przepływem
Funkcja switch()Wektorowe ifelse()repeat i breakFunkcje rekurencyjnePodsumowanie — klasyfikator ocen2Wyszukiwanie wartości po kluczach
Wyszukiwanie nazwanych elementów wektoraSprawdzanie kluczyDodawanie i usuwanie kluczyIterowanie po nazwachPowtórzenie — giełda5Projekt — dziennik ocen
Dodawanie uczniówZapisywanie ocen8Sortowanie i grupowanie
Sortowanie wektorówSortowanie według kluczaGrupowanie za pomocą split()Podsumowania grupPowtórka – tabela wyników11Obsługa błędów
Zgłaszanie błędów za pomocą stop()Przechwytywanie błędów za pomocą tryCatch()Ostrzeżenia i finallyWalidacja danych wejściowychPodsumowanie – bezpieczny kalkulator3Zbiory i zliczanie
Unikalne wartościOperacje na zbiorachTesty przynależnościZliczanie za pomocą table()Podsumowanie — goście wydarzenia6Funkcje jako wartości
Funkcje anonimowePrzekazywanie funkcjiZwracanie funkcjiDomknięcia ze stanemPowtórka — reguły rabatowe9Ramki danych
Tworzenie ramek danychKolumny i wierszeFiltrowanie wierszyDodawanie i sortowaniePodsumowanie – raport sprzedaży12Projekt – śledzenie wydatków
Rejestrowanie wydatkówŁączne wydatkiPoćwicz samodzielnie: Kompilator R online