Nathan T Alexander
Nathan T Alexander

Reputation: 257

Why is RMarkdown not displaying code output?

I am using RStudio on Windows 10. Please help me get the output of the R System function to be included in my output document when I knit the markdown file. I have tried many combinations of chunk options that I found in the official reference.

In the Console, the output of:

system('java -version')

is:

java version "1.8.0_261"
Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode)

However, when I put it into an RMardown document:

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

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

Unfortunately, instead of showing my java version, the formatted output for the chunk is:

## [1] 0

Upvotes: 0

Views: 1489

Answers (1)

r2evans
r2evans

Reputation: 160407

Up front, use:

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

(If you want to make sure that any command called, not just java, then (1) assume it accepts -version, and (2) also add stdout = TRUE. If there is no stdout to capture, then it does not harm.)

Why?

This is a (quick) discussion about file descriptors (fd). When a program runs, it may accept data (or something) on file descriptor 0, which is typically known as standard input or stdin. It can emit (send text/values/data) out on any number of file descriptors, but typically most programs use at least fd1 (standard output, stdout) and often but not always fd2 (standard error, stderr). The reason is so that command-line utilities can capture intended output on stdout and capture errors/warnings on stderr. In shell-speak:

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

Will send the intended (normal) output to the file output.log, and anything non-standard (or out-of-band or warnings or debugging or ...) to error.log. In many circumstances, an empty error.log is a good thing and "expected".

During my initial testing, since I don't have java, I was using ls --version, and /bin/ls sends its version information out on stdout. Apparently, java uses stderr.

(I finally verified with by switching to a command which should use stderr: the easiest way to reproduce without java around was:

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

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

which (1) did not have the expected ls: unknown option -- versiommmmm output, and (2) returned ## [1] 2 instead, indicating an exit status of 2. (Most utilities use an exit status of 0 to mean "all good", and anything else as an error. Some utilities go so far as the emit a specific exit status for specific errors, but it's generally safe to assume "not 0 means some error condition".)

In order to get R to do a system call and catch the stderr, I switched to system2, which allows one to capture stderr= (as well as stdout= separately).

Notes:

  • system2 takes the command to run as its first argument, and then all subsequent arguments as a character vector, so something like:

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

    would call java with two arguments, "Echo" and the string. (Actually, that's not quite right ... see the next bullet.)

  • both system and system2 do really poor jobs of quoting things. If any of your arguments have embedded spaces, such as the call in the previous bullet, then the command will actually seem individual arguments. So the previous bullet's command actually calls java with four arguments, and is equivalent to c("Echo", "Drink", "Hot", "Java"). (I and many people consider this a significant problem with system2. The workarounds include using shQuote yourself or using the processx package, which does things right.)

  • different arguments, where the equivalent of system(..., intern=TRUE) is system2(..., stdout=TRUE) ... and you gain the ability to use stderr=.

Upvotes: 1

Related Questions