12.4 Truncate text output

When the text output from a code chunk is lengthy, you may want to only show the first few lines. For example, when printing a data frame of a few thousand rows, it may not be helpful to show the full data, and the first few lines may be enough. Below we redefine the output hook so that we can control the maximum number of lines via a custom chunk option out.lines:

# save the built-in output hook
hook_output <- knitr::knit_hooks$get("output")

# set a new output hook to truncate text output
knitr::knit_hooks$set(output = function(x, options) {
  if (!is.null(n <- options$out.lines)) {
    x <- xfun::split_lines(x)
    if (length(x) > n) {
      # truncate the output
      x <- c(head(x, n), "....\n")
    }
    x <- paste(x, collapse = "\n")
  }
  hook_output(x, options)
})

The basic idea of the above hook function is that if the number of lines of the text output is greater than the threshold set in the chunk option out.lines (stored in the variable n in the function body), we only keep the first n lines and add an ellipsis (....) to indicate the output is truncated.

Now we can test the new output hook by setting the chunk option out.lines = 4 on the chunk below:

print(cars)
##    speed dist
## 1      4    2
## 2      4   10
## 3      7    4
....

And you see four lines of output as expected. Since we have stored the original output hook in hook_output, we can restore it by calling the set() method again:

knitr::knit_hooks$set(output = hook_output)

As an exercise for readers, you may try to truncate the output in a different way: given the chunk option out.lines to determine the maximum number of lines, can you truncate the output in the middle instead of the end? For example, if out.lines = 10, you extract the first and last five lines, and add .... in the middle like this:

##    speed dist
## 1      4    2
## 2      4   10
## 3      7    4
## 4      7   22
....
## 46    24   70
## 47    24   92
## 48    24   93
## 49    24  120
## 50    25   85

Please note that the last line in the output (i.e., the argument x of the hook function) might be an empty line, so you may need something like c(head(x, n/2), '....', tail(x, n/2 + 1)) (+ 1 to take the last empty line into account).