Pander
is designed to
provide a minimal and easy tool for rendering R
objects
into Pandoc’s markdown. This vignette
aims to introduce the pander
package and its core pieces of
functionality. It is intended to be a general overview with pointers to
places with detailed information. This vignette will talk about:
Pandoc
’s
markdown with generic S3 pander
method.The core functionality of pander
is centered around
rendering R
objects into Pandoc
’s markdown.
Let’s dive in to a demo of the most common usage of
pander
:
pander(head(iris))
#>
#> -------------------------------------------------------------------
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> -------------- ------------- -------------- ------------- ---------
#> 5.1 3.5 1.4 0.2 setosa
#>
#> 4.9 3 1.4 0.2 setosa
#>
#> 4.7 3.2 1.3 0.2 setosa
#>
#> 4.6 3.1 1.5 0.2 setosa
#>
#> 5 3.6 1.4 0.2 setosa
#>
#> 5.4 3.9 1.7 0.4 setosa
#> -------------------------------------------------------------------
pander(head(mtcars[1:5]))
#>
#> --------------------------------------------------------
#> mpg cyl disp hp drat
#> ----------------------- ------ ----- ------ ----- ------
#> Mazda RX4 21 6 160 110 3.9
#>
#> Mazda RX4 Wag 21 6 160 110 3.9
#>
#> Datsun 710 22.8 4 108 93 3.85
#>
#> Hornet 4 Drive 21.4 6 258 110 3.08
#>
#> Hornet Sportabout 18.7 8 360 175 3.15
#>
#> Valiant 18.1 6 225 105 2.76
#> --------------------------------------------------------
pander(tabular( (Species + 1) ~ (n=1) + Format(digits=2)*
(Sepal.Length + Sepal.Width)*(mean + sd), data=iris ))
#>
#> -----------------------------------------------------------------
#> Sepal.Length Sepal.Width
#> Species n mean sd mean sd
#> ------------ ----- ---------------- ------ --------------- ------
#> setosa 50 5.01 0.35 3.43 0.38
#>
#> versicolor 50 5.94 0.52 2.77 0.31
#>
#> virginica 50 6.59 0.64 2.97 0.32
#>
#> All 150 5.84 0.83 3.06 0.44
#> -----------------------------------------------------------------
As you have probably guessed, this is achieved via the generic
pander
S3
method. Out of the box,
pander
supports a variety of classes:
methods(pander)
#> [1] pander.Arima* pander.CrossTable* pander.Date*
#> [4] pander.Glm* pander.NULL* pander.POSIXct*
#> [7] pander.POSIXlt* pander.anova* pander.aov*
#> [10] pander.aovlist* pander.call* pander.cast_df*
#> [13] pander.character* pander.clogit* pander.coxph*
#> [16] pander.cph* pander.data.frame* pander.data.table*
#> [19] pander.default* pander.density* pander.describe*
#> [22] pander.ets* pander.evals* pander.factor*
#> [25] pander.formula* pander.ftable* pander.function*
#> [28] pander.glm* pander.gtable* pander.htest*
#> [31] pander.image* pander.irts* pander.list*
#> [34] pander.lm* pander.lme* pander.logical*
#> [37] pander.lrm* pander.manova* pander.matrix*
#> [40] pander.microbenchmark* pander.name* pander.nls*
#> [43] pander.numeric* pander.ols* pander.orm*
#> [46] pander.polr* pander.prcomp* pander.randomForest*
#> [49] pander.rapport* pander.rlm* pander.sessionInfo*
#> [52] pander.smooth.spline* pander.stat.table* pander.summary.aov*
#> [55] pander.summary.aovlist* pander.summary.glm* pander.summary.lm*
#> [58] pander.summary.lme* pander.summary.manova* pander.summary.nls*
#> [61] pander.summary.polr* pander.summary.prcomp* pander.summary.rms*
#> [64] pander.summary.survreg* pander.summary.table* pander.survdiff*
#> [67] pander.survfit* pander.survreg* pander.table*
#> [70] pander.tabular* pander.ts* pander.zoo*
#> see '?methods' for accessing help and source code
If you think that pander lacks support for any other R class(es), please feel free to open a ticket suggesting a new feature or submit pull request and we will be happy to extend the package.
Under the hood, pander
S3 methods rely on different
pandoc.*
methods, where most of functionality is
implemented in pandoc.table
which is used for rendering
tables. pandoc.table
provides functionality similar to
knitr::kable
in rendering markdown, but also adds a truly
rich functionality with a variety of rendering options inherited from
pander
. For more usage/implementation details and examples,
please refer to the pandoc.table
vignette, which can be
accessed by vignette('pandoc_table')
(and is also available
online).
The pander
package was originally developed in
conjunction with rapport package, when a
need arose for a function that could evaluate R
expressions
while also capturing errors and warnings. So evals
emerged
and soon some further feature requests arose, like identifying if an R
expression results in a plot, etc.
But probably it’s easier to explain what evals
can do
with a simple example:
evals('1:10')
#> INFO [2024-11-07 05:44:22] Command run: 1:10
#> TRACE [2024-11-07 05:44:22] Cached result
#> DEBUG [2024-11-07 05:44:22] Returned object: class = integer, length = 10, dim = , size = 96 bytes
#> [[1]]
#> $src
#> [1] "1:10"
#>
#> $result
#> [1] 1 2 3 4 5 6 7 8 9 10
#>
#> $output
#> [1] " [1] 1 2 3 4 5 6 7 8 9 10"
#>
#> $type
#> [1] "integer"
#>
#> $msg
#> $msg$messages
#> NULL
#>
#> $msg$warnings
#> NULL
#>
#> $msg$errors
#> NULL
#>
#>
#> $stdout
#> NULL
#>
#> attr(,"class")
#> [1] "evals"
evals
is aimed at collecting as much information as
possible while evaluating R code. It can evaluate a character vector of
R expressions, and it returns a list of information captured while
running them:
src
holds the R expression,result
contains the raw R object as-is,output
represents how the R object is printed to the
standard output,type
is the class of the returned R object,msg
is a list of possible messages captured while
evaluating the R expression. Among other messages, warnings/errors will
appear here.stdout
contains what, if anything, was written to the
standard output.For more usage/implementation details and examples, please refer to
the evals
vignette, which can be accessed by
vignette('evals')
(also available online).
The brew package, a templating framework for report generation, has not been updated since 2011, but it’s still some of R projects based on its simple design and useful literate programming features. For a quick overview, please see the following documents if you are not familiar with brew:
A brew document is a simple text file with some special tags.
Pandoc.brew
uses only two of them (as building on a
personalized version of Jeff’s really great brew function):
<% ... %>
stands for running inline R commands as
usual,<%= ... %>
does pretty much the same but applies
pander to the returning R object (instead of cat
like the
original brew function does). So inserting any R object into the tag
would return it in Pandoc markdown format, with all possible
error/warning messages, etc.The latter tries to be smart in some ways:
R
commands between the tags) can
return any number of values at any part of the block.R
commands (e.g. those taking more then 0.1
sec to evaluate) are cached so rebrewing a report would not result in a
coffee break.Besides this, the custom brew function can do more and also less compared to the original brew package. First of all, the internal caching mechanism of brew has been rewritten for benefits besides improved caching. Quick example:
str(Pandoc.brew(text ='Pi equals to `<%= pi %>`. And here are some random data: `<%= runif(10)%>`'))
#> Pi equals to `INFO [2024-11-07 05:44:22] Command run: pi
#> TRACE [2024-11-07 05:44:22] Cached result
#> DEBUG [2024-11-07 05:44:22] Returned object: class = numeric, length = 1, dim = , size = 56 bytes
#> _3.142_`. And here are some random data: `INFO [2024-11-07 05:44:22] Command run: runif(10)
#> TRACE [2024-11-07 05:44:22] Cached result
#> DEBUG [2024-11-07 05:44:22] Returned object: class = numeric, length = 10, dim = , size = 176 bytes
#> _0.39_, _0.7773_, _0.9606_, _0.4347_, _0.7125_, _0.4_, _0.3254_, _0.7571_, _0.2027_ and _0.7111_`
#> List of 1
#> $ :List of 4
#> ..$ type : chr "text"
#> ..$ text :List of 2
#> .. ..$ raw : chr "Pi equals to `<%=pi%>`. And here are some random data: `<%=runif(10)%>`\n"
#> .. ..$ eval: chr "Pi equals to `_3.142_`. And here are some random data: `_0.39_, _0.7773_, _0.9606_, _0.4347_, _0.7125_, _0.4_, "| __truncated__
#> ..$ chunks:List of 2
#> .. ..$ raw : chr [1:2] "<%=pi%>" "<%=runif(10)%>"
#> .. ..$ eval: chr [1:2] "_3.142_" "_0.39_, _0.7773_, _0.9606_, _0.4347_, _0.7125_, _0.4_, _0.3254_, _0.7571_, _0.2027_ and _0.7111_"
#> ..$ msg :List of 3
#> .. ..$ messages: NULL
#> .. ..$ warnings: NULL
#> .. ..$ errors : NULL
The package bundles some examples for Pandoc.brew
to let
you quickly check its features. To brew these examples on your machine,
run the following commands:
Pandoc.brew(system.file('examples/minimal.brew', package='pander'))
Pandoc.brew(system.file('examples/minimal.brew', package='pander'),
output = tempfile(), convert = 'html')
Pandoc.brew(system.file('examples/short-code-long-report.brew', package='pander'))
Pandoc.brew(system.file('examples/short-code-long-report.brew', package='pander'),
output = tempfile(), convert = 'html')
Pandoc.brew(system.file('examples/graphs.brew', package='pander'))
Pandoc.brew(system.file('examples/graphs.brew', package='pander'),
output = tempfile(), convert = 'html')
The package comes with a variety of globally adjustable options that
have an effect on the result of your reports. A full list of options can
be viewed by calling ?panderOptions
or in the online readme.
You can query and update these options with the
panderOptions
function:
pots <- panderOptions("table.style")
panderOptions("table.style", "simple")
pander(mtcars[1:3, 1:4])
#>
#>
#> mpg cyl disp hp
#> ------------------- ------ ----- ------ -----
#> Mazda RX4 21 6 160 110
#> Mazda RX4 Wag 21 6 160 110
#> Datsun 710 22.8 4 108 93
pander(head(iris))
#>
#>
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> -------------- ------------- -------------- ------------- ---------
#> 5.1 3.5 1.4 0.2 setosa
#> 4.9 3 1.4 0.2 setosa
#> 4.7 3.2 1.3 0.2 setosa
#> 4.6 3.1 1.5 0.2 setosa
#> 5 3.6 1.4 0.2 setosa
#> 5.4 3.9 1.7 0.4 setosa
panderOptions("table.style", "grid")
pander(head(iris))
#>
#>
#> +--------------+-------------+--------------+-------------+---------+
#> | Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
#> +==============+=============+==============+=============+=========+
#> | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
#> +--------------+-------------+--------------+-------------+---------+
#> | 4.9 | 3 | 1.4 | 0.2 | setosa |
#> +--------------+-------------+--------------+-------------+---------+
#> | 4.7 | 3.2 | 1.3 | 0.2 | setosa |
#> +--------------+-------------+--------------+-------------+---------+
#> | 4.6 | 3.1 | 1.5 | 0.2 | setosa |
#> +--------------+-------------+--------------+-------------+---------+
#> | 5 | 3.6 | 1.4 | 0.2 | setosa |
#> +--------------+-------------+--------------+-------------+---------+
#> | 5.4 | 3.9 | 1.7 | 0.4 | setosa |
#> +--------------+-------------+--------------+-------------+---------+
panderOptions("table.style", pots)