--- title: "Using pander with knitr" author: "Roman Tsegelskyi, Gergely Daróczi" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Using pander with knitr} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, echo = FALSE, message = FALSE} knitr::opts_chunk$set(collapse = T, comment = "#>") library(pander) library(knitr) ``` While the report generation functionality of `pander` and `knitr` do overlap, we feel that the most powerful way to use `R/knitr/pander` for report generation is to utilize them together. This short vignette aims to explain how to embed `pander` output in reports generated by `knitr`. If you are not aware of `knitr`, be sure to check out the project's [homepage](https://yihui.org/knitr/) for extensive documentation and examples. One of `knitr`'s most useful features is the ability to convert tables to output format on the fly. For example: ```{r} head(iris) knitr::kable(head(iris)) ``` However, `kable` table generator is simple by design, and does not capture all the variety of classes that `R` has to offer. For example, `CrossTable` and `tabular` are not supported: ```{r, error = TRUE} library(descr, quietly = TRUE) ct <- CrossTable(mtcars$gear, mtcars$cyl) knitr::kable(ct) library(tables, quietly = TRUE) tab <- tabular( (Species + 1) ~ (n=1) + Format(digits=2)* (Sepal.Length + Sepal.Width)*(mean + sd), data=iris ) knitr::kable(tab) ``` This is where `pander` comes in handy, as `pander` supports rendering for many popular classes: ```{r} methods(pander) ``` Also, `pander` is integrated with `knitr` by default. `pander` simply identifies if `knitr` is running in the background, and if so, it uses `capture.output` to return the resulting string as an `knit_asis` object, meaning that you do not need to specify the `results='asis'` option in your knitr chunk: ```{r, error = TRUE} library(descr, quietly = TRUE) pander(CrossTable(mtcars$gear, mtcars$cyl)) library(tables, quietly = TRUE) tab <- tabular( (Species + 1) ~ (n=1) + Format(digits=2)* (Sepal.Length + Sepal.Width)*(mean + sd), data=iris ) pander(tab) ``` In a nutshell, this is achieved by modification that whenever you call `pander` inside of a `knitr` document, instead of returning the markdown text to the standard output (the default behavior), `pander` returns a `knit_asis` class object, which renders correctly in the resulting document — without the double comment chars, thus properly rendering the tables in HTML, PDF, or other document formats. If you don't want the results of `pander` to be converted automatically, just set `knitr.auto.asis` to `FALSE` using `panderOptions`: ```{r} panderOptions('knitr.auto.asis', FALSE) pander(head(iris)) ``` ```{r} panderOptions('knitr.auto.asis', TRUE) ``` #### Rendering markdown inside loop/vectorized function One frequenly asked question is how to use `pander` with `knitr` in a loop or vectorized function. For example, we have 3 tables that we want to render using `lapply`: ```{r} dfs <- list(mtcars[1:3, 1:4], mtcars[4:6, 1:4], mtcars[7:9, 1:4]) lapply(dfs, pander) ``` As you can see, this doesn't work correctly because `pander` tries to return a `knit_asis` class object when run inside `knitr`, but for loops/vectorized functions this results in incorrect output. The recommended way to solve this is to disable this behavior by setting `knitr.auto.asis` to `FALSE` using `panderOptions`. However, we also need to tell `knitr` to convert the table on the fly by specifying `results='asis'` in the chunk options: ```{r results='asis'} panderOptions('knitr.auto.asis', FALSE) dfs <- list(mtcars[1:3, 1:4], mtcars[4:6, 1:4], mtcars[7:9, 1:4]) invisible(lapply(dfs, pander)) ```