'R markdown to PDF - Printing console output

I am working in RStudio for a course, and I want to write up my reports with R markdown. I would like to display certain console output in the pdf that will be the report, specifically the output of summary(model) where model is e.g. a linear model obtained by using the command lm. The default seems however to be that the console output, after conversion to pdf with knitr, is displayed as-is and with '#'-symbols in front of it, which is both ugly to me and also quite cumbersome to deal with when tweaking the final layout of the report.

Is there any nicer way to display console output, specifically when converting my notebooks to pdf? Ideally, I would like something like a box surrounding the output (HTML conversion seems to give you just that) and optimally be able to add a caption to state what the output is representing. And most of all, no annoying '#'-signs on every row.

I have tried searching around here and googling for a solution, but I haven't found anything that solves my problem.



Solution 1:[1]

Here is a workaround. The idea is to transform console output in text that you can plot and custom as you like.

---
title: "Untitled"
output:
  pdf_document: default
---

```{r, echo = F}
print_output <- function(output, cex = 0.7) {
  tmp <- capture.output(output)
  plot.new()
  text(0, 1, paste(tmp, collapse='\n'), adj = c(0,1), family = 'mono', cex = cex)
  box()
}
```

```{r, warning = F}
lm <- lm(mpg ~ hp, data = mtcars)

print_output(summary(lm))
```

which gives: enter image description here

Solution 2:[2]

Here is another approach using knitr hooks. We simply wrap additional LaTeX commands around the chunk output.

TOC:

  1. Basic solution using the latex package framed.
  2. Flexible solution using the latex package fancyvrb

1. Basic solution using the latex package framed.

---
title: "Output Hook"
output: pdf_document
---

```{r setup, include = F}
library(knitr)
opts_chunk$set(comment=NA)
def_hook <- knit_hooks$get("output")
knit_hooks$set(output = function(x, options) {
  out <- def_hook(x, options)
  return(paste("\\begin{framed}\\begin{verbatim}", x, "\\end{verbatim}\\end{framed}", collapse = "\n"))
})
```

```{r}
lm(mpg ~ hp, data = mtcars)
```

enter image description here

2. Flexible solution using the latex package fancyvrb

You could even modify the outcome in a very flexible way using the latex package fancyvrb (see this documentation for options):

---
title: "Output Hook"
output: pdf_document
header-includes:
  - \DefineVerbatimEnvironment{myVerb}{Verbatim}{numbers=left,numbersep=1mm,frame=lines,framerule=0.4mm,rulecolor=\color{blue}}
---

```{r setup, include = F}
library(knitr)
opts_chunk$set(comment=NA)
def_hook <- knit_hooks$get("output")
knit_hooks$set(output = function(x, options) {
  out <- def_hook(x, options)
  return(paste("\\begin{myVerb}\n", x, "\\end{myVerb}", collapse = "\n"))
})
```

```{r}
lm(mpg ~ hp, data = mtcars)
```

enter image description here

Solution 3:[3]

Getting rid of the ## is a display option in rmarkdown, which is comment = "" for any chunk or opts_chunk$set(comment=NA) in your first code chunk for the whole document.

Also you should look at the pander package for "nice" printing of outputs.

Solution 4:[4]

To complement the first option suggested by Martin, you could use the LaTeX package mdframed (instead of framed) to get more flexibility and add, for example, a background colour (in the example below, 10% red).

---
title: "Output Hook"
output: pdf_document
header-includes: 
  \usepackage{mdframed}
---

```{r setup, include = F}
library(knitr)
opts_chunk$set(comment = NA)
def_hook <- knit_hooks$get("output")
knit_hooks$set(output = function(x, options){
  out <- def_hook(x, options)
  return(paste("\\begin{mdframed}[backgroundcolor=red!10]\\begin{verbatim}", x,
               "\\end{verbatim}\\end{mdframed}", collapse = "\n"))
})
```

```{r}
lm(mpg ~ hp, data = mtcars)
```

enter image description here

(This is following this answer to a similar question posted in LaTeX Stack Exchange. In short, while it is possible to define a background color using framed, as other people I find it easier to do so using mdframed)

Solution 5:[5]

In case this is useful for someone, I have also been playing with the LaTeX package tcolorbox for more advanced customisation. In this example, I defined some colours and a format for R console outputs, auto numbering each output and giving it a "title". This was useful to be able to cross-reference outputs in tutorials.

---
title: "Output Hook"
output: pdf_document
header-includes: 
  \usepackage[most]{tcolorbox}
  \definecolor{iacol}{RGB}{246, 130, 18}
---

```{=latex}
\newtcolorbox[auto counter]{ROut}[2][]{
                lower separated=false,
                colback=white,
                colframe=iacol,
                fonttitle=\bfseries,
                colbacktitle=iacol,
                coltitle=black,
                boxrule=1pt,
                sharp corners,
                breakable,
                enhanced,
                attach boxed title to top left={yshift=-0.1in,xshift=0.15in},
                boxed title style={boxrule=0pt,colframe=white,},
              title=#2,#1}
```

```{r setup, include = FALSE}
library(knitr)
opts_chunk$set(comment = NA)
def_hook <- knit_hooks$get("output")
knit_hooks$set(output = function(x, options){
  out <- def_hook(x, options)
  return(paste("\\begin{ROut}{R console: Output~\\thetcbcounter}
                \\begin{footnotesize}
                \\begin{verbatim}", 
               x,
               "\\end{verbatim}
                \\end{footnotesize}
                \\end{ROut}"))
})
```

An example of code and output.

```{r}
lm(mpg ~ hp, data = mtcars)
```

Another example of code and output.

```{r}
summary(lm(mpg ~ hp + disp + drat, data = mtcars))
```

This example produces this document: enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Elin
Solution 4
Solution 5 Juan David Leongomez