Showing only the first few lines of the results of a code chunk

I'm using R Markdown to create some documentation about R. I'd like some of my code chunks to illustrate what R returns, but I don't always want ALL the resulting output. Is there a way to limit the number of lines returned by a chunk? Sort of a head() but for the results of a code chunk?

3 Likes

You can write a custom output hook function to achieve this with knitr.

@yihui answered a StackOverflow question with a neat example of writing a hook function:

```{r}
library(knitr)
hook_output <- knit_hooks$get("output")
knit_hooks$set(output = function(x, options) {
  lines <- options$output.lines
  if (is.null(lines)) {
    return(hook_output(x, options))  # pass to default hook
  }
  x <- unlist(strsplit(x, "\n"))
  more <- "..."
  if (length(lines)==1) {        # first n lines
    if (length(x) > lines) {
      # truncate the output, but add ....
      x <- c(head(x, lines), more)
    }
  } else {
    x <- c(more, x[lines], more)
  }
  # paste these lines together
  x <- paste(c(x, ""), collapse = "\n")
  hook_output(x, options)
})
``` 

Normal output.

```{r test}
summary(lm(Sepal.Length ~ Species, data=iris))
```

The first 4 lines.

```{r test, output.lines=4}
```

Remove the first 8 lines.

```{r test, output.lines=-(1:8)}
```

From 8 to 15.

```{r test, output.lines=8:15}
```
7 Likes

Andrie, thank you so much! That's exactly what I was looking for. I had this vague notion that I had seen it somewhere previously. I suspect it was that SO question. Thanks for the Sunday answer!

I'm hitting a weird implementation snag, however. If I hide the hook code at the top of a chapter in a code block, it seems to work great. I'm doing a multi chapter book and I plan on using this over and over. So it makes sense to me to add it to my _common.R file which is referenced in my _bookdown.yaml as a before chapter script:

before_chapter_script: "_common.R"

So my understanding is that the _common.R gets sourced on the top of each chapter before it is rendered. However if I add the hook_output code chunk I get the following error:

==> rmarkdown::render_site(encoding = 'UTF-8')

R -e 'bookdown::render_book("index.Rmd", output=bookdown::gitbook())'

R version 3.4.4 (2018-03-15) -- "Someone to Lean On"
Copyright (C) 2018 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin15.6.0 (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> bookdown::render_book("index.Rmd", output=bookdown::gitbook())


processing file: index.Rmd
  |................................                                 |  50%
label: unnamed-chunk-1 (with options) 
List of 2
 $ include: logi FALSE
 $ cache  : logi FALSE

  |.................................................................| 100%
   inline R code fragments


output file: index.knit.md



processing file: 01_GettingStarted.Rmd
  |.                                                                |   1%
label: unnamed-chunk-1 (with options) 
List of 2
 $ include: logi FALSE
 $ cache  : logi FALSE

  |..                                                               |   3%
label: unnamed-chunk-2 (with options) 
List of 2
 $ include: logi FALSE
 $ cache  : logi FALSE

  |...                                                              |   4%
label: unnamed-chunk-3 (with options) 
List of 2
 $ include: logi FALSE
 $ cache  : logi FALSE

  |....                                                             |   6%
  ordinary text without R code

  |.....                                                            |   7%
label: unnamed-chunk-4 (with options) 
List of 2
 $ echo: logi FALSE
 $ eval: logi TRUE

  |.....                                                            |   8%
  ordinary text without R code

  |......                                                           |  10%
label: unnamed-chunk-5

Error in substring(file, 1L, 1L) : node stack overflow
Calls: local ... hook_output -> hook_output -> .handleSimpleError -> h -> cat
Execution halted
Error in Rscript_render(f, render_args, render_meta) : 
  Failed to compile 01_GettingStarted.Rmd
Calls: <Anonymous> ... render_new_session -> tryCatch -> tryCatchList -> Rscript_render
Execution halted
make: *** [book] Error 1
Error in render_book_script(output_format, envir, quiet) : 
  Error 2 attempting to render book
Calls: <Anonymous> -> <Anonymous> -> in_dir -> render_book_script
Execution halted

Exited with status 1.

And this is mighty verbose, but here's my _common.R file in its entirety:

set.seed(42)
options(digits = 3)

library(tidyverse)
library(knitr)

knitr::opts_chunk$set(
  comment = "#>",
  collapse = TRUE,
  cache = TRUE,
  out.width = "70%",
  fig.align = 'center',
  fig.width = 6,
  fig.asp = 0.618,  # 1 / phi
  fig.show = "hold"
)

options(dplyr.print_min = 6, dplyr.print_max = 6)

hook_output <- knit_hooks$get("output")
knit_hooks$set(output = function(x, options) {
  lines <- options$output.lines
  if (is.null(lines)) {
    return(hook_output(x, options))  # pass to default hook
  }
  x <- unlist(strsplit(x, "\n"))
  more <- "etc ..."
  if (length(lines)==1) {      # first n lines
    if (length(x) > lines) {   # truncate the output, but add ....
      x <- c(head(x, lines), more)
    }
  } else {
    x <- c(more, x[lines], more)
  }
  # paste these lines together
  x <- paste(c(x, ""), collapse = "\n")
  hook_output(x, options)
})

I'm sorry, but I don't know the answer to your question.

I'll try to call on some reinforcements!

Thank you, Andrie. I've made it work by including the chunk at the beginning of each chapter. Clearly there's something about before_chapter_script: behavior that I don't understand or know how to debug.

Thanks again for all your help.

-J