R 스크립트 줄 번호 오류?


105

명령 줄 (R --slave script.R)에서 긴 R 스크립트를 실행하는 경우 오류시 줄 번호를 제공하려면 어떻게해야합니까?

가능한 경우 스크립트에 디버그 명령을 추가하고 싶지 않습니다. R이 대부분의 다른 스크립팅 언어처럼 동작하기를 원합니다.


31
업데이트가 있습니까? 4 년 후, R의 모든 주류 채택에도 불구하고 문제가 여전히 지속되는 것 같습니다.
Gui Ambros 2013 년

나는 또한 많은 작은 출력을 가진 매우 긴 R 스크립트를 가지고 있습니다. 라인 번호를 하드 코딩하는 대신 C에서 (밑줄) (밑줄) LINE / FILE (밑줄) (밑줄) (줄 번호 및 스크립트 이름)을 인쇄하고 싶습니다. 소스로.
mosh 2016

R이 내부적으로 실제로 '줄 번호'개념을 가지고 있는지 모르겠습니다. 그러나 그것은 완전한 작업, 즉 최상위 작업이라는 개념을 가지고 있습니다. 예를 들어 어떤 최상위 작업이 실패했는지 알려주는 작업 처리기를 쉽게 정의 할 수 있습니다. 물론 큰 사슬이나 큰 조건문을 가진 사람들에게는 큰 위안이 아닙니다.
russellpierce

답변:


45

이것은 줄 번호를 제공하지 않지만 호출 스택에서 오류가 발생하는 위치를 알려줍니다. 이는 매우 유용합니다.

traceback()

[편집 :] 명령 줄에서 스크립트를 실행할 때 한두 번의 호출을 건너 뛰어야 합니다. 대화 형 및 비대화 형 R 세션에 대해서는 traceback ()을 참조하십시오.

일반적인 디버깅 용의자없이이 작업을 수행하는 다른 방법을 알지 못합니다.

  1. 디버그 ()
  2. 브라우저 ()
  3. options (error = recover) [되돌리려면 options (error = NULL)가 이어짐]

이 관련 게시물을보고 싶을 수 있습니다.

[편집 :] 죄송합니다 ... 명령 줄에서 실행중인 것을 봤습니다. 이 경우 옵션 (오류) 기능을 사용하는 것이 좋습니다. 다음은 간단한 예입니다.

options(error = quote({dump.frames(to.file=TRUE); q()}))

오류 조건에 대해 원하는대로 정교한 스크립트를 만들 수 있으므로 디버깅에 필요한 정보를 결정해야합니다.

그렇지 않고, 당신이 염려하는 특정 영역이 있다면 (예 : 데이터베이스에 연결), tryCatch () 함수로 감싸십시오.


첫 번째 [Edit :] 블록에 연결된 솔루션이 저에게 효과적입니다. 가장 좋은 접근 방식은 @dshepherd의 주석 인 것 같습니다. 즉, 추가합니다 options(error=function() { traceback(2); if(!interactive()) quit("no", status = 1, runLast = FALSE) })(수락 된 답변의 주석 참조). 다른 스레드에 대한 링크 만 제공하는 것보다 여기에 답변에 추가하는 것이 합리적이라고 생각합니다.
cryo111


13

Doing options(error=traceback)은 오류로 이어지는 행의 내용에 대한 정보를 조금 더 제공합니다. 오류가있는 경우 트레이스 백이 나타나고 일부 오류의 경우 접두사가 붙은 줄 번호가 #있습니다. 그러나 히트 또는 실패, 많은 오류가 줄 번호를 얻지 못합니다.


2
나를 위해 잘 작동하지 않습니다. 파일이 하나 뿐이며 줄 번호가 표시되지 않고 No traceback available오류가 발생한 후에 만 표시됩니다.
Mark Lakata

11

이에 대한 지원은 R 2.10 이상에서 제공 될 예정입니다. Duncan Murdoch는 2009 년 9 월 10 일에 findLineNum 및 setBreapoint 에 대해 r-devel에 게시했습니다 .

디버깅을 돕기 위해 R-devel에 몇 가지 기능을 추가했습니다. findLineNum()소스 코드의 특정 줄에 해당하는 함수의 줄을 찾습니다. setBreakpoint()의 출력을 취하고 거기에 중단 점을 설정하기 위해 findLineNum호출 trace()합니다.

이는 코드에 소스 참조 디버그 정보가 있어야합니다. 에서 읽은 코드의 기본값 source()이지만 패키지에는 적용되지 않습니다. 패키지 코드에서 소스 참조를 가져 오려면 환경 변수를 설정 R_KEEP_PKG_SOURCE=yes하거나 R 내에서 설정 options(keep.source.pkgs=TRUE)한 다음 소스 코드에서 패키지를 설치합니다. ?findLineNum검색을 전역 환경으로 제한하지 않고 패키지 내에서 검색하도록 지시하는 방법에 대한 자세한 내용을 읽으십시오 .

예를 들면

x <- " f <- function(a, b) {
             if (a > b)  {
                 a
             } else {
                 b
             }
         }"


eval(parse(text=x))  # Normally you'd use source() to read a file...

findLineNum("<text>#3")   # <text> is a dummy filename used by
parse(text=)

이것은 인쇄됩니다

 f step 2,3,2 in <environment: R_GlobalEnv>

그리고 당신은 사용할 수 있습니다

setBreakpoint("<text>#3")

거기에 중단 점을 설정합니다.

코드에는 여전히 몇 가지 제한 (그리고 아마도 버그)이 있습니다. 나는 thos를 고칠거야


감사. r-devel 메일 링리스트에도 가입했습니다. 나는 그것이 내받은 편지함을 막을 것이라는 가정하에 r-help를 피하고 있습니다 (r-sig-finance는 이미 그것을하고 있습니다).
Shane

1
R 스크립트를
살펴 보지

1
@hirse : 이것은 거의 10 개의 예전 답변입니다. 도대체 왜 내가 인용 한 것처럼 보이도록 포맷을 변경 했나요? 나는 그렇지 않았고 당신의 변화는 내 의도를 반영 하지 않습니다 .
Dirk Eddelbuettel

"Duncan Murdoch가 방금 게시했습니다 :"는 인용구처럼 들리지만 정확하지 않은 경우 편집 내용을 되 돌리십시오. 더 읽기 쉽게 만들고 싶었고 끝날 때까지 날짜를 확인하지 않았습니다. 전체 답변이 너무 오래된 경우 삭제하여 향후 독자에게 혼란을주지 않도록 할 수도 있습니다.
hirse

되돌릴 수 있습니까? 감사합니다.
Dirk Eddelbuettel

6

설정하여 수행

options(show.error.locations = TRUE)

이 설정이 R에서 기본값이 아닌 이유가 궁금합니다. 다른 모든 언어와 마찬가지로 그래야합니다.


1
이 옵션에 대한 배경 정보를 참조 stat.ethz.ch/R-manual/R-devel/library/base/html/options.html
R 요다

1
이전에는 작동했지만 신뢰할 수 없기 때문에 비활성화되었습니다. 궁극적으로 무료가 아닌 RStudio를 사용하도록 강요하려는 시도라고 생각합니다.
에릭 Leschinski

6
나는 그것을 의심한다. R core와 RStudio는 매우 다른 조직이며 특히 R core는 견고한 오픈 소스입니다.
Ben Bolker

CentOS 6.9, R-3.4.2에서 작업
irritable_phd_syndrom

코드를 소싱하기 전에 먼저 옵션을 설정해야합니다.
JAponte

3

치명적이지 않은 오류를 처리하기위한 전역 R 옵션을 지정하면 오류에 대한 정보를 유지하고 실패 후이 정보를 검사하는 사용자 지정 워크 플로와 함께 저에게 효과적이었습니다. 현재 R 버전 3.4.1을 실행하고 있습니다. 아래에는 저에게 도움이 된 워크 플로에 대한 설명과 R에서 전역 오류 처리 옵션을 설정하는 데 사용한 일부 코드가 포함되어 있습니다.

내가 구성했듯이 오류 처리는 오류 발생시 작업 메모리의 모든 개체를 포함하는 RData 파일도 생성합니다. 이 덤프는를 사용하여 R로 다시 읽을 수 있으며 load()오류 발생 당시 존재했던 다양한 환경은를 사용하여 대화식으로 검사 할 수 있습니다 debugger(errorDump).

traceback()스택 내의 모든 사용자 지정 함수 의 출력에서 줄 번호를 얻을 수 있었지만 스크립트에 사용 된 사용자 지정 함수를 keep.source=TRUE호출 할 때 옵션을 사용한 경우에만 해당됩니다 source(). 이 옵션이 없으면 아래와 같이 전역 오류 처리 옵션을 설정하면의 전체 출력 traceback()이라는 오류 로그로 전송 error.log되지만 줄 번호를 사용할 수 없습니다.

다음은 워크 플로에서 수행 한 일반적인 단계와 비대화 형 R 실패 후 메모리 덤프 및 오류 로그에 액세스 할 수 있었던 방법입니다.

  1. 명령 줄에서 호출 한 기본 스크립트의 맨 위에 다음을 넣었습니다. 이것은 R 세션에 대한 전역 오류 처리 옵션을 설정합니다. 내 주요 스크립트는 myMainScript.R. 코드의 여러 줄에는 작업을 설명하는 주석이 있습니다. 기본적으로이 옵션을 사용하면 R에서를 트리거하는 오류가 발생 stop()하면 디렉터리의 모든 활성 환경에서 작업 메모리의 RData (*. rda) 덤프 파일을 ~/myUsername/directoryForDump만들고 error.log유용한 정보가 포함 된 오류 로그 를 같은 디렉토리. 이 스 니펫을 수정하여 오류에 대한 다른 처리를 추가 할 수 있습니다 (예 : 덤프 파일 및 오류 로그 파일 이름에 타임 스탬프 추가 등).

    options(error = quote({
      setwd('~/myUsername/directoryForDump'); # Set working directory where you want the dump to go, since dump.frames() doesn't seem to accept absolute file paths.
      dump.frames("errorDump", to.file=TRUE, include.GlobalEnv=TRUE); # First dump to file; this dump is not accessible by the R session.
      sink(file="error.log"); # Specify sink file to redirect all output.
      dump.frames(); # Dump again to be able to retrieve error message and write to error log; this dump is accessible by the R session since not dumped to file.
      cat(attr(last.dump,"error.message")); # Print error message to file, along with simplified stack trace.
      cat('\nTraceback:');
      cat('\n');
      traceback(2); # Print full traceback of function calls with all parameters. The 2 passed to traceback omits the outermost two function calls.
      sink();
      q()}))
  2. 기본 스크립트 및 후속 함수 호출에서 함수가 제공 될 때마다 옵션 keep.source=TRUE이 사용 되는지 확인하십시오 . 즉, 함수를 소싱하려면 source('~/path/to/myFunction.R', keep.source=TRUE). traceback()출력에 줄 번호가 포함 되는 데 필요 합니다. 를 사용하여이 옵션을 전역 적으로 설정할 수도있는 것 options( keep.source=TRUE )같지만 작동하는지 확인하기 위해 테스트하지는 않았습니다. 줄 번호가 필요하지 않은 경우이 옵션을 생략 할 수 있습니다.

  3. 터미널 (R 외부)에서를 사용하여 배치 모드로 기본 스크립트를 호출합니다 Rscript myMainScript.R. 이렇게하면 새로운 비대화 형 R 세션이 시작되고 스크립트가 실행됩니다 myMainScript.R. 상단에 배치 된 1 단계에서 제공된 코드 조각 myMainScript.R은 비대화 형 R 세션에 대한 오류 처리 옵션을 설정합니다.
  4. 실행 중에 오류가 발생했습니다 myMainScript.R. 이것은 메인 스크립트 자체에 있거나 여러 함수를 깊게 중첩 할 수 있습니다. 오류가 발생하면 1 단계에서 지정한대로 처리가 수행되고 R 세션이 종료됩니다.
  5. errorDump.rda및 이름이 지정된 RData 덤프 파일 과 이름 error.log이 지정된 오류 로그 '~/myUsername/directoryForDump'가 전역 오류 처리 옵션 설정에 지정된 디렉토리에 생성됩니다 .
  6. 여유 시간에 error.log오류 메시지 자체 및 오류로 이어지는 전체 스택 추적을 포함하여 오류에 대한 정보를 검토하십시오. 다음은 오류 발생시 생성되는 로그의 예입니다. #문자 뒤의 숫자는 호출 스택의 여러 지점에서 오류의 줄 번호입니다.

    Error in callNonExistFunc() : could not find function "callNonExistFunc"
    Calls: test_multi_commodity_flow_cmd -> getExtendedConfigDF -> extendConfigDF
    
    Traceback:
    3: extendConfigDF(info_df, data_dir = user_dir, dlevel = dlevel) at test_multi_commodity_flow.R#304
    2: getExtendedConfigDF(config_file_path, out_dir, dlevel) at test_multi_commodity_flow.R#352
    1: test_multi_commodity_flow_cmd(config_file_path = config_file_path, 
    spot_file_path = spot_file_path, forward_file_path = forward_file_path, 
    data_dir = "../", user_dir = "Output", sim_type = "spot", 
    sim_scheme = "shape", sim_gran = "hourly", sim_adjust = "raw", 
    nsim = 5, start_date = "2017-07-01", end_date = "2017-12-31", 
    compute_averages = opt$compute_averages, compute_shapes = opt$compute_shapes, 
    overwrite = opt$overwrite, nmonths = opt$nmonths, forward_regime = opt$fregime, 
    ltfv_ratio = opt$ltfv_ratio, method = opt$method, dlevel = 0)
  7. 여가 시간 errorDump.rda에는를 사용하여 대화 형 R 세션에 로드 할 수 있습니다 load('~/path/to/errorDump.rda'). 로드되면 debugger(errorDump)모든 활성 환경에서 메모리의 모든 R 개체를 찾아보기 위해 호출 합니다. 자세한 내용은 R 도움말을 참조하십시오 debugger().

이 워크 플로는 명령 줄에서 비대화 형 R 세션이 시작되고 예상치 못한 오류에 대한 정보를 유지하려는 일부 유형의 프로덕션 환경에서 R을 실행할 때 매우 유용합니다. 오류 발생시 작업 메모리를 검사하는 데 사용할 수있는 파일에 메모리를 덤프하는 기능과 함께 호출 스택에 오류 줄 번호가 있으면 오류의 원인을 사후 디버깅 할 수 있습니다.


0

먼저, options(show.error.locations = TRUE)다음 traceback(). 오류 줄 번호는 # 뒤에 표시됩니다.

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