[r] R에서 패키지 작성을 위해 message ()가 print ()보다 나은 선택 인 이유는 무엇입니까?
진단 메시지를 인쇄 할 message()
때보 다 왜 더 나은 선택 인지 알고 싶습니다 print()
.
예를 들어, print()
함수 'iris'
는와 같은 R 객체를 인쇄하는 데 더 나은 선택 이지만, message()
문자열을 연결하려는 경우 message("a", "b")
에는 더 좋습니다 print(paste0("a", "b"))
.
그러나 위에 나열된 단순한 것보다 더 많은 차이점이 있다고 생각합니다. 두 가지 방법에 대한 설명서를 읽었습니다.
- http://stat.ethz.ch/R-manual/R-devel/library/base/html/message.html ,
- http://stat.ethz.ch/R-manual/R-devel/library/base/html/print.html
그러나 내 질문에 기대했던 것만 큼 유익하지 않은 것 같습니다.
누군가가 어떤 경우 message()
보다 낫고 print()
그 이유를 알려 주시면 감사하겠습니다 .
답변
TL; DR
S3 객체에 cat()
대한 print.*()
함수를 만들 때 사용해야 합니다. 그 밖의 모든 message()
경우에는 프로그램 상태에 문제가없는 한 사용해야합니다 . 예를 들어 복구 가능한 잘못된 오류는 오류를 warning()
중지 하는 것과 비교합니다 stop()
.
골
이 게시물의 목적은 패키지 개발자가 액세스 할 수있는 다양한 출력 옵션에 대한 피드백을 제공하고 잠재적으로 새 객체 또는 문자열을 기반으로하는 출력을 구성하는 방법을 제공하는 것입니다.
R 출력 개요
기존의 출력 기능은 다음과 같습니다.
이제 처음 두 함수 ( print()
및 cat()
)는 출력을 stdout
또는 표준 출력으로 보냅니다 . 마지막 세 함수 ( message()
, warning()
및 stop()
)는 출력을 stderr
또는 표준 오류 로 보냅니다 . 즉, 다음 과 같은 명령 의 결과 출력 은 lm()
하나의 파일로 전송되고 오류 출력 (있는 경우)은 완전히 별도의 파일로 전송됩니다. 이는 진단이 로그 파일의 결과 출력을 복잡하게 하지 않고 오류를 신속하게 검색 할 수 있으므로 사용자 경험에 특히 중요합니다 .
사용자 및 외부 패키지를위한 디자인
이제 위의 내용은 I / O 사고 방식에 더 많이 포함되어 있으며 반드시 사용자를 향한 프레임 셋은 아닙니다. 따라서 일상적인 R 사용자의 맥락에서 이에 대한 동기 부여를 제공하겠습니다. 특히, 3-5 또는 사용하여 stderr
기능들이 출력 통해 콘솔 텍스트 땜질 않고 억제 할 수있다 sink()
나 capture.output()
. 억제는 일반적으로 suppressWarnings()
,, suppressMessages()
등 의 형태로 제공 suppressPackageStartupMessages()
됩니다. 따라서 사용자는 결과에 직면 한 결과에만 직면하게됩니다. 이는 knitr , rmarkdown 또는 Sweave 를 통해 동적 문서를 만들 때 사용자가 텍스트 기반 출력을 해제 할 수있는 유연성을 허용하려는 경우 특히 중요합니다 .
특히, knitr
같은 청크 옵션을 제공합니다 error = F
, message = F
하고 warning = F
. 이를 통해 문서에서 명령에 수반되는 텍스트를 줄일 수 있습니다. 또한 results = "hide"
모든 출력을 비활성화 하는 옵션을 사용할 필요가 없습니다 .
출력의 특성
인쇄()
먼저, 우리는 오래된 사람이지만 좋은 사람이 있습니다 print()
. 이 기능에는 몇 가지 심각한 제한이 있습니다. 그중 하나는 용어의 내장 된 연결이 없다는 것입니다. 두 번째, 아마도 더 심각한 것은 각 출력 앞에 [x]
실제 내용에 대한 인용문 이 뒤따른 다는 사실입니다 . x
이 경우는 요소 번호가 인쇄되기 말한다. 이것은 디버깅 목적에 도움이되지만 그 외에는 어떤 용도로도 사용되지 않습니다.
예 :
print("Hello!")
[1] "Hello!"
연결의 경우 다음 paste()
과 동기화하여 작동 하는 함수에 의존합니다 print()
.
print(paste("Hello","World!"))
[1] "Hello World!"
또는 의 매개 변수 에 의해 관리되는 요소 사이 의 기본 사용을 피하기 위해 paste0(...)
대신 함수를 사용할 수 있습니다 . (공백없는 연결)paste(...)
spacepaste()
sep = " "
예 :
print(paste0("Hello","World!"))
[1] "HelloWorld!"
print(paste("Hello","World!", sep = ""))
[1] "HelloWorld!"
고양이()
반대로, cat()
이러한 모든 비판을 다룹니다. 대부분의 특히, sep=" "
의 매개 변수 paste()
기능은 쓰기를 건너 뛸 하나를 수에 내장되어 paste()
내 cat()
. 그러나 cat()
함수의 유일한 단점은 \n
끝 부분에 추가 또는 fill = TRUE
(기본 인쇄 너비 사용) 를 통해 새 줄을 강제로 적용해야한다는 것 입니다.
예 :
cat("Hello!\n")
Hello!
cat("Hello","World!\n")
Hello World!
cat("Hello","World!\n", sep = "")
HelloWorld!
이것이 바로 S3 방법을 cat()
설계 할 때 사용해야하는 이유 print.*()
입니다.
메시지()
message()
기능도보다 한 단계 더 cat()
! 출력되는 이유는 stderr
대신에 지정 되는 기존 일반 텍스트와 다릅니다 stdout
. 예 : 사용자의 시선을 사로 잡기 위해 표준 검정 출력에서 빨간색 출력으로 색상을 변경했습니다.
또한 내장 paste0()
기능이 있습니다.
message("Hello ","World!") # Note the space after Hello
"Hello World!"
또한 다음 message()
과 함께 사용할 수있는 오류 상태를 제공합니다.tryCatch()
예 :
tryCatch(message("hello\n"), message=function(e){cat("goodbye\n")})
goodbye
경고()
이 warning()
기능은 부담없이 사용할 수있는 것이 아닙니다. 경고 기능은 주로 접두어 ( "Warning message:"
)에 행이 추가되어 메시지 기능과 구별 되며 그 상태는 문제가있는 것으로 간주됩니다.
기타 : 함수에서 우연히 사용하면 일반적으로 “오류”로 처리되는 예제 검사 및 경고로 인해 패키지를 CRAN 에 업로드하는 동안 실수로 비탄을 유발할 수 있습니다 .
중지()
마지막으로 stop()
. 이것은 당면한 작업을 완전히 종료하고 사용자에게 제어권을 되돌림으로써 경고를 다음 단계로 가져옵니다. 또한 "Error:"
추가 되는 용어와 함께 가장 심각한 접두사가 있습니다.