【问题标题】:How should I select how to print with R? [closed]我应该如何选择如何使用 R 打印? [关闭]
【发布时间】:2016-03-17 15:38:53
【问题描述】:

在 R 中显示文本的方法有很多:catprintwritewriteLinessinkmessage,以及其他我现在不记得的替代方法。这里和互联网上的其他地方还有其他问题比较其中一些,但它们通常只涵盖两个或三个。某处必须有一个表格或图表来简要总结它们之间的差异。是的,我查了手册,大部分都分不清。

更新:在我发布这个问题后,其他人提出了一个非常相似的问题,得到了很好的回应:Why is message() a better choice than print() in R for writing a package?。由于此问题已关闭,我无法将其标记为重复或添加答案,所以我只留下此注释。

【问题讨论】:

  • 这是一个懒惰的问题...您只是在这里抛出了一堆函数名称,并希望有人为您写一篇涵盖所有方面/用例/等的论文。换取一些虚构的互联网积分。我认为你至少应该在你身边表现出一些努力。除非您正在寻找一些场外教程 - 在这种情况下,这里是 OT。
  • 如果答案是否定的,这将是很棒的,这不存在,你可以做到并把它放在社区的某个地方。
  • 大多数用户经常使用/需要的唯一一个是print(通常只被隐式调用)。您的问题不应该是这些函数如何比较,而是如果您想做一些不同于正常打印到控制台的特定操作,应该使用哪个函数。
  • 我不同意这是一个懒惰的问题。在无数次搜索它的一些变化后,我决定问它。还有其他问题询问何时使用某个功能,并且通常有几个正确答案暗示不同的答案。我不想只是在不理解的情况下复制和粘贴。将问题重命名为“为什么 R 有这么多打印方式”会更好吗?
  • 对于任何来这里的人,在我发布这个问题大约一个月后,其他人发布了一个非常相似的问题,被认为合适并获得了很多选票:stackoverflow.com/questions/36699272/…

标签: r


【解决方案1】:

这是一个很好的问题,因为 R 以许多稍微不同的方式来完成类似任务而臭名昭著。

函数print 用于简单地打印到R 控制台。例如:

# a sample vector
tmp<-c("foo","bar","baz")
tmp
# [1] "foo" "bar" "baz"

print(tmp)
#[1] "foo" "bar" "baz"

另外值得注意的是print可以在加载其他包后获得新的打印方式,例如xtable包。

cat 函数将传递给它的所有条目连接起来,并以更类似于您可能更习惯的命令行或 shell(例如 bash)的方式打印它们。例如:

cat(tmp)
# foo bar baz

paste 函数一样,它也可以包含分隔符,并允许 R 提取其他技巧:

cat(tmp,sep = "|")
# foo|bar|baz
# handy for creating complex regular expressions

# create some LaTeX markup
FigureFilepath<-"/path/to/figure/i.jpg"
cat("\\includegraphics[width=0.9\\linewidth,height=0.9\\textheight,keepaspectratio]{", FigureFilepath, "}\n", sep="")
# \includegraphics[width=0.9\linewidth,height=0.9\textheight,keepaspectratio]{/path/to/figure/i.jpg}

正如暗示的那样,如果您在环境中使用 R,例如在带有 knitr 的 LaTeX 文档中并想要打印特殊格式的文本,这可能会很方便。

write 函数是 cat 的包装器,它打印到文件并对矩阵进行了一些特殊处理(此处未显示):

write(tmp,file = "output.txt")
file.show("output.txt")
# foo
# bar
# baz

虽然 OP 没有提及它,但我认为提及 paste 函数很重要,包括它的表亲 paste0paste 函数还将项目打印到控制台,这些项目在视觉上类似于print,例如:

paste(tmp)
# [1] "foo" "bar" "baz"

但是,存在一些显着差异。您还可以组合来自不同向量的元素,并指定分隔符:

paste(tmp,c("one","two"),sep = "~")
# [1] "foo~one" "bar~two" "baz~one"
# Note how the second element is recycled here!

您还可以collapse 输出将所有内容与另一个指定的分隔符连接在一起:

paste(tmp,c("one","two"),sep = "~",collapse = "|")
# [1] "foo~one|bar~two|baz~one"

如果你只是想要一个快速简单的,你可以使用paste0,它不使用分隔符,但也可以支持collapse

paste0(tmp,c("one","two"))
# [1] "fooone" "bartwo" "bazone"

重要的是,pastepaste0 的输出可以保存为对象或在另一个函数中使用,这与 Richard 的评论中的 cat 不同。

x<-paste(tmp,c("one","two"),sep = "~")
x
# [1] "foo~one" "bar~two" "baz~one"

如果您尝试将printcat 的输出保存到一个对象中,这是控制台输出:

> x<-print("yes")
[1] "yes"
> x
[1] "yes"
> x<-cat("yes")
yes
> x
NULL

大多数 R 初学者通常会遇到的另一个症结是在 for 循环中使用 printpaste。在for 循环内执行时,paste 的控制台输出不显示,如下所示:

for(i in 1){
  paste("This is paste")
  print("This is print")
  cat("This is cat")
}
# [1] "This is print"
# This is cat

sink 函数只是将 R 控制台输出转移到文件中。

sink("output.txt")
cat("hello")
cat("\n")
cat("world")
print(tmp)
sink()
# hello
# world[1] "foo" "bar" "baz"

请注意,在两个 sink() 命令之间写入控制台的任何内容都将写入文件,这可能是不可取的。

writeLines 函数可以与“连接”类型的对象一起使用,以便将输出发送到其他地方,通常是文件。与sink 不同,它只会将指定的项目写入文件。

fileConn<-file("output.txt")
writeLines(tmp,fileConn)
cat("This is test text")
print("Hello world")
close(fileConn)
file.show("output.txt")
# foo
# bar
# baz

您可以为此提出一些创造性的用途,例如在脚本末尾创建系统会话日志

fileConn<-file("syslog.txt")
writeLines(capture.output(system('uname -srv',intern=T),sessionInfo()), fileConn)
close(fileConn)
# file.show("syslog.txt")
# <too long to fit here!>

有一些很好的解释解释了为什么其中一些函数也能以它们在此博客中的方式工作:http://arrgh.tim-smith.us/atomic.html

【讨论】:

  • 所有关于paste 的内容都与问题无关。 paste 根本不打印。它返回一个字符向量(如果您不使用catmessagewarningwrite 等,它会通过调用print 来打印)。
  • 好点 Roland,感谢您的澄清。初学者错误地使用paste 打印到控制台是很常见的,因此我将它包含在我对R中“打印”文本的一些方法的解释中。
猜你喜欢
  • 2014-12-27
  • 2010-09-25
  • 1970-01-01
  • 2023-03-19
  • 2016-06-19
  • 1970-01-01
  • 2013-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多