R에서 trycatch를 작성하는 방법


342

trycatch웹에서 다운로드 할 때 오류를 처리하는 코드 를 작성하고 싶습니다 .

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)

이 두 문장은 성공적으로 실행됩니다. 아래에 존재하지 않는 웹 주소를 만듭니다.

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

url[1]존재하지 않는다. 어떻게 편지 않습니다 trycatch있도록 루프 (기능) :

  1. URL이 잘못되면 "웹 URL이 잘못되어 얻을 수 없습니다"라는 출력이 표시됩니다.
  2. URL이 잘못되면 코드가 중지되지 않지만 URL 목록이 끝날 때까지 계속 다운로드됩니까?

답변:


626

그럼 : R 세계에 오신 것을 환영합니다 ;-)

여기 요

코드 설정

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

코드 적용

> 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

출력 조사

> 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

추가 비고

tryCatch

tryCatchexpr오류나 경고가없는 한 실행과 관련된 값을 반환합니다 . 이 경우 return(NA)각각의 핸들러 함수를 제공하여 특정 반환 값 ( 위 참조 )을 지정할 수 있습니다 (인수 errorwarningin 참조 ?tryCatch). 이것들은 이미 존재하는 함수 일 수 있지만 tryCatch()(위에서 한 것처럼) 내부에서 정의 할 수도 있습니다 .

핸들러 함수의 특정 리턴 값 선택의 의미

NA오류가 발생했을 때 반환되도록 지정 했으므로 in의 세 번째 요소는 y입니다 NA. 우리가 선택한 싶은 경우 NULL반환 값의 길이로 y불과했을 2대신 3으로 lapply()단순히 반환 값을 "무시"됩니다 NULL. 를 통해 명시적인 반환 값을 지정하지 않으면 return()처리기 함수가 반환됩니다 NULL(예 : 오류 또는 경고 조건).

"원치 않는"경고 메시지

warn=FALSE사용하는 것입니다 영향, (이 경우에는 정말 관심을하지 않은) 경고를 억제하는 다른 방법이 보이지 않는다

suppressWarnings(readLines(con=url))

대신에

readLines(con=url, warn=FALSE)

여러 표현

당신은 또한 (인수은 "실제 표현 부분"여러 표현을 배치 할 수 있습니다 exprtryCatch()당신이 (필자는 도시처럼 중괄호를 포장하는 경우) finally일부).


paste함수 의 첫 번째 문자열 이 공백으로 끝나는 경우 공백과 sep=""?
seancarmody

2
@seancarmody : true ;-) 더 길거나 더 복잡한 문자열을 모으는 데 익숙해 져 실제로 실제로 작성하여 공백을 제어해야했습니다.
Rappster

3
당신은 그것을 사용해야 paste0합니다!
seancarmody

6
paste0() 이다 베이스. 내부적으로, 모두 paste()paste0()통화 do_paste에서 paste.c . 유일한 차이점은 인수를 paste0()전달하지 않는다는 것 sep입니다.
jthetzel

1
@JulienNavarre : "시도 부분"은 항상 마지막 개체 (현재 readLines(con=url, warn=FALSE)는 잘못 될 수있는 개체)를 반환합니다 . 따라서 메시지를 추가하려면 실제 retun 값을 변수에 저장해야합니다. out <- readLines(con=url, warn=FALSE)그 다음에 실제로 반환되는 마지막 객체를 만들기 위해 message("Everything worked")다음에옵니다out
Rappster

69

R은 try-catch 블록을 구현하기위한 함수를 사용합니다.

문법은 다음과 같습니다 :

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

tryCatch ()에는 처리 할 수있는 '경고'와 '오류'라는 두 가지 '조건'이 있습니다. 각 코드 블록을 작성할 때 이해해야 할 중요한 사항은 실행 상태와 범위입니다. @출처


5
교체 error-handler-codecat("web url is wrong, can't get")
seancarmody

2
메시지 캐치 아웃
rawr

52

tryCatch약간 복잡한 구문 구조를 가지고 있습니다. 그러나 아래와 같이 완전한 tryCatch 호출을 구성하는 4 개의 파트를 이해하면 기억하기 쉬워집니다.

expr : [ 필수 ] 평가할 R 코드

error : [ 선택 사항 ] expr에서 코드를 평가하는 동안 오류가 발생한 경우 실행해야 할 사항

warning : [ 선택 사항 ] expr에서 코드를 평가하는 동안 경고가 발생한 경우 실행해야 할 사항

finally : [ 선택 사항 ] expr이 성공적으로 실행되었는지, 오류 또는 경고가 있는지에 관계없이 tryCatch 호출을 종료하기 직전에 실행해야 할 사항

tryCatch(
    expr = {
        # Your code...
        # goes here...
        # ...
    },
    error = function(e){ 
        # (Optional)
        # Do this if an error is caught...
    },
    warning = function(w){
        # (Optional)
        # Do this if an warning is caught...
    },
    finally = {
        # (Optional)
        # Do this at the end before quitting the tryCatch structure...
    }
)

따라서 값의 로그를 계산하는 장난감 예제는 다음과 같습니다.

log_calculator <- function(x){
    tryCatch(
        expr = {
            message(log(x))
            message("Successfully executed the log(x) call.")
        },
        error = function(e){
            message('Caught an error!')
            print(e)
        },
        warning = function(w){
            message('Caught an warning!')
            print(w)
        },
        finally = {
            message('All done, quitting.')
        }
    )    
}

이제 세 가지 경우를 실행하십시오.

유효한 경우

log_calculator(10)
# 2.30258509299405
# Successfully executed the log(x) call.
# All done, quitting.

"경고"사례

log_calculator(-10)
# Caught an warning!
# <simpleWarning in log(x): NaNs produced>
# All done, quitting.

"오류"사례

log_calculator("log_me")
# Caught an error!
# <simpleError in log(x): non-numeric argument to mathematical function>
# All done, quitting.

정기적으로 사용하는 유용한 사용 사례에 대해 작성했습니다. 자세한 내용은 여기를 참조하십시오. https://rsangole.netlify.com/post/try-catch/

이것이 도움이 되길 바랍니다.


34

다음은 간단한 예입니다 .

# 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("This is my custom message.")
            message("And below is the error message from R:")
            message(error_message)
            return(NA)
        }
    )
}

"경고"를 캡처 warning=하려면 error=부품 과 유사하게 추가하십시오 .


1
expr한 줄 대신 두 줄이 있기 때문에 부품 주위에 중괄호가 있어야합니까 ?
Paul

감사! 이중 점검 후, 중괄호가 필요하지 않습니다
Paul

다시 확인해 주셔서 감사합니다. 코드를 실행하면 Error: unexpected ')' in " )"및이 Error: unexpected ')' in " )"있습니다. 중괄호 쌍을 추가하면 문제가 해결됩니다.
Paul

대부분의 사용 사례에 맞습니다. 감사합니다. 수정되었습니다.
Paul

23

irC 함수에 대한 tryCatch를 해결하려고 노력하면서 이틀 동안 목숨을 잃었으므로 지혜를 공유해야한다고 생각했습니다. FYI-irr은 FinCal의 실제 함수이며이 경우 큰 데이터 세트에서 몇 가지 경우 오류가 발생했습니다.

  1. tryCatch를 함수의 일부로 설정하십시오. 예를 들면 다음과 같습니다.

    irr2 <- function (x) {
      out <- tryCatch(irr(x), error = function(e) NULL)
      return(out)
    }
  2. 오류 (또는 경고)가 작동하려면 실제로 함수를 작성해야합니다. 나는 원래 오류 부분에 대해 쓰고 error = return(NULL)모든 값이 null로 돌아 왔습니다.

  3. 하위 출력 (예 : "out")과 to를 작성해야 return(out)합니다.


3
3 번이 왜 필요한가요?
jan-glx
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.