为什么message()比R中的print()更适合编写包?

Kim*_*Kim 56 r

我希望知道为什么message()print()打印诊断信息更好.

例如,print()函数是打印R对象的更好选择,例如'iris',message()当我们想要连接字符串时,它更好,例如message("a", "b")短于print(paste0("a", "b")).

但是,我认为与上面列出的简单差异相比,存在更多差异.我已经阅读了这两种方法的文档

但是,似乎它们并没有像我希望的那样提供信息.

如果有人告诉我们哪种情况message()比哪种情况更好print(),为什么我会感激.

coa*_*ess 99

TL; DR

您应该cat()print.*()为S3对象创建函数时使用.除此之外,您应该使用message()除非程序状态有问题.例如,可恢复的错误错误给出了warning()显示停止错误使用stop().

目标

这篇文章的目的是提供有关包开发人员可以访问的不同输出选项的反馈,以及如何构造可能在新对象上或基于字符串的输出.

R输出概述

传统的输出功能是:

  1. print()
  2. cat()
  3. message()
  4. warning()
  5. stop()

现在,前两个函数(print()cat())将其输出发送到stdout标准输出.最后三个函数(message(),warning()stop())将其输出发送到stderr标准错误.也就是说,从类似命令输出结果lm()被发送到一个文件,并且错误输出(如果存在)被发送到完全独立的文件.这对于用户体验尤其重要,因为诊断不会使日志文件中的结果输出混乱,然后可以快速搜索错误.

设计用户和外部包

现在,上面的内容更多地是I/O思维模式,而不一定是面向用户的框架集.所以,让我们在日常R用户的背景下为它提供一些动力.特别是,通过使用3-5或stderr函数,可以在不修改控制台文本的情况下抑制它们的输出sink().抑制通常进来的形式capture.output(),suppressWarnings(),suppressMessages(),等等.因此,用户只面临面向输出的结果.如果您计划通过knitr,rmarkdownSweave创建动态文档时允许用户灵活地关闭基于文本的输出,这一点尤为重要.

特别是,suppressPackageStartupMessages()提供块选项,如knitr,error = Fmessage = F.这使得能够减少伴随文档中的命令的文本.此外,这可以防止使用warning = F禁用所有输出的选项.

输出细节

results = "hide"

首先,我们有一个老人,但有一个好东西,print().此功能有一些严重的限制.其中之一是缺乏嵌入式术语串联.第二个,可能更严重的是,每个输出[x]之后都是实际内容周围的引号.在x这种情况下指的是正在打印的元件数目.这有助于调试目的,但除此之外它不起任何作用.

例如

print("Hello!")

[1] "Hello!"
Run Code Online (Sandbox Code Playgroud)

对于连接,我们依赖于paste()print()以下同步工作的功能:

print(paste("Hello","World!"))

[1] "Hello World!"
Run Code Online (Sandbox Code Playgroud)

可替代地,人们可以使用该paste0(...)功能来代替paste(...),以避免使用默认的space管辖元件之间paste()sep = " "参数.(又名没有空格的连接)

例如

print(paste0("Hello","World!"))

[1] "HelloWorld!"

print(paste("Hello","World!", sep = ""))

[1] "HelloWorld!"
Run Code Online (Sandbox Code Playgroud)

cat()

另一方面,sep=" "解决了所有这些批评.最值得注意的是,该paste()的参数paste()的功能是建立在允许一个跳跃写入cat()cat().但是,该\n功能唯一的缺点是你必须通过fill = TRUE附加的末尾强制换行或cat()(使用默认的打印宽度).

例如

cat("Hello!\n")
Hello!

cat("Hello","World!\n")
Hello World!

cat("Hello","World!\n", sep = "")
HelloWorld!
Run Code Online (Sandbox Code Playgroud)

正是出于这个原因,您应该print.*()在设计message()S3方法时使用它.

cat()

stderr功能是一步比甚至更好stdout!原因是输出与传统的纯文本不同,因为它是针对的paste0()而不是message().例如,他们将颜色从标准黑色输出更改为红色输出以吸引用户的眼球.

消息输出

此外,您还具有内置tryCatch()功能.

message("Hello ","World!") # Note the space after Hello
"Hello World!"
Run Code Online (Sandbox Code Playgroud)

此外,warning()提供可以使用的错误状态"Warning message:"

例如

 tryCatch(message("hello\n"), message=function(e){cat("goodbye\n")})
 goodbye
Run Code Online (Sandbox Code Playgroud)

stop()

警告功能不是随便使用的.警告功能主要通过为其预先添加一行("警告消息:")来区分消息功能,并且其状态被认为是有问题的.

警告输出

其他:由于示例检查和警告通常被视为"错误",因此在尝试将程序包上传到CRAN时,函数中的临时使用可能会无意中触发心碎.

"Error:"

最后但同样重要的是,我们有cat().这会通过完全杀死手头的任务并将控制权返回给用户来将警告提升到下一级别.此外,它有最严重的附属物,添加了"错误:"一词.

错误输出

  • 感谢您的精彩回应。我一直在寻找类似的东西,但我的问题被标记为“懒惰”:http://stackoverflow.com/questions/36065232/how-should-i-select-how-to-print-with-r (2认同)