【问题标题】:Why is RMarkdown not displaying code output?为什么 RMarkdown 不显示代码输出?
【发布时间】:2020-08-28 20:24:02
【问题描述】:

我在 Windows 10 上使用 RStudio。当我编写 markdown 文件时,请帮助我将 R System 函数的输出包含在我的输出文档中。我尝试了许多在official reference 中找到的块选项组合。

在控制台中,输出:

system('java -version')

是:

java版本“1.8.0_261”
Java(TM) SE 运行时环境(内部版本 1.8.0_261-b12)
Java HotSpot(TM) 64 位服务器 VM(内部版本 25.261-b12,混合模式)

但是,当我将它放入 RMardown 文档时:

---
title: "Code Chunk Not Displaying Output"
output: html_document
---

```{r test}
system('java -version')
```

不幸的是,该块的格式化输出不是显示我的 java 版本,而是:

## [1] 0

【问题讨论】:

  • 来自?system"intern: 一个逻辑(非NA),指示是否将命令的输出捕获为R字符向量"。试试system("java -version", intern=TRUE)。 (您看到的是退出代码,其中“0”通常表示“未遇到错误”。)
  • 试试system2("java", "--version", stdout=TRUE, stderr=TRUE)
  • r2evans 有效!想要做出官方的回答吗?请注意,它应该是 -version 而不是 --version
  • 还有一件事,stdout 参数不是必需的,这有效:system2("java", "-version", stderr=TRUE)

标签: r r-markdown


【解决方案1】:

在前面,使用:

system2("java", "-version", stderr = TRUE)

(如果您想确保调用了 any 命令,而不仅仅是java,那么(1)假设它接受-version,并且(2)还添加stdout = TRUE。如果没有stdout可以捕获,那么它不会造成伤害。)

为什么?

这是关于文件描述符 (fd) 的(快速)讨论。当程序运行时,它可能会接受文件描述符 0 上的数据(或其他内容),这通常称为 标准输入stdin。它可以在任意数量的文件描述符上发出(发送文本/值/数据),但通常大多数程序至少使用 fd1(标准输出stdout)并且经常但不总是使用 fd2(标准错误,stderr)。原因是命令行实用程序可以在stdout 上捕获预期输出,并在stderr 上捕获错误/警告。用shell说话:

#                         /-- this is redirecting stdout
#                         |            /-- this is redirecting stderr
#                         v            v
$ somecommand -arg1 -arg2 > output.log 2> error.log

将预期(正常)输出发送到文件output.log,并将任何非标准(或带外或警告或调试或...)发送到error.log。在许多情况下,一个空的error.log 是一件好事并且是“预期的”。

在我最初的测试期间,由于我没有 java,我使用的是ls --version,而/bin/ls 将其版本信息发送到stdout。显然,java 使用了stderr

(我最终通过切换到应该使用stderr 的命令进行验证:没有java 的最简单的重现方法是:

---
title: "Code Chunk Not Displaying Output"
output: html_document
---

```{r test}
system("ls --versiommmmm", intern = TRUE)
```

其中 (1) 没有预期的 ls: unknown option -- versiommmmm 输出,并且 (2) 返回了 ## [1] 2,表示退出状态为 2。(大多数实用程序使用退出状态 0 表示“一切正常”,以及其他任何错误。一些实用程序甚至会针对特定错误发出特定的退出状态,但通常可以安全地假设“不是0 表示某些错误条件”。)

为了让 R 进行系统调用并捕获标准错误,我切换到system2,它允许捕获stderr=(以及单独的stdout=)。

注意事项:

  • system2 将要运行的命令作为其第一个参数,然后将所有后续参数作为字符向量,例如:

    system2("java", c("Echo", "Drink Hot Java"))
    

    会用两个参数调用java"Echo" 和字符串。 (实际上,这不太对……请看下一条。)

  • systemsystem2 在引用事物方面做得很差。如果您的任何参数都嵌入了空格,例如上一个项目符号中的调用,那么该命令实际上将看起来像是单独的参数。所以上一个子弹的命令实际上是用四个参数调用java,相当于c("Echo", "Drink", "Hot", "Java")。 (我和许多人都认为这是 system2 的一个重大问题。解决方法包括自己使用 shQuote 或使用 processx 包,它可以正确。)

  • 不同的参数,其中system(..., intern=TRUE) 的等价物是system2(..., stdout=TRUE) ...并且您可以使用stderr=

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多