Overview

pander is an R package containing helpers to return Pandoc's markdown even automatically from several type of R objects with a general S3 method.

The package is also capable of exporting/converting complex Pandoc documents (reports) in three ways at the moment:

How does pander differ from Sweave, brew, knitr, R2HTML etc.?

Installation

The stable version of the package can be found on CRAN and can be installed easily in the R console:

install.packages('pander')

On the other hand I welcome everyone to use the most recent version of the package with added features and currently hosted on GitHub. The current build status is:

It can be installed easily with the nifty function of devtools package:

library(devtools)
install_github('pander', 'Rapporter')

Or download the sources in a zip file and build manually. If you're running R on Windows, you need to install Rtools.

Depends

pander heavily builds on Pandoc which should be pre-installed before trying to convert your reports to different formats. Although main functions work without Pandoc, e.g. you can generate a markdown formatted report via Pandoc.brew or the custom reference class, but I would really suggest to install that really great piece of software!

The installation process of Pandoc is quite straightforward on most operating systems: just download and run the binary (a few megabytes), and get a full-blown document converted in a few seconds/minutes. On different Linux distributions it might be a bit more complicated (as repositories tend to provide out-dated versions of Pandoc, so you would need cabal-install to install from sources). Please do not forget to restart your R session to update your PATH after installation!

An alternative method (bypassing Pandoc dependency) would be to call the awesome markdown package to transform markdown (as far as I know: exclusively) to HTML.

And as pander and rapport are quite Siamese twins, you would need an up-to-date version of rapport most likely installed from Github. pander now can work independently from rapport.

Now you would only need a few cool packages from CRAN:

Helper functions

There are a bunch of helper functions in pander which e.g. return user specified inputs in Pandoc format or applies some extra formatting on those. For a technical documentation, see the HTML help files of the package at help.r-enthusiasts.com.

Primitive functions

You could find the Pandoc-related functions starting with pandoc. - for example pandoc.strong would return the passed characters with strong emphasis. E.g.:

> pandoc.strong('FOO')
**FOO**>
> pandoc.strong.return('FOO')
[1] "**FOO**"

As it can be seen here pandoc functions generally prints to console and do not return anythingby default (see: ?cat). If you want the opposite (get the Pandoc format as a string): call each function ending in .return - like the second call in the above example. For details please check documentation, e.g. ?pandoc.strong.

The full list of primitive Pandoc-related functions are:

Lists

Of course there are more complex functions too. Besides verbatim texts, (image) links or footnotes (among others) there are a helper e.g. for lists:

> l <- list("First list element", paste0(1:5, '. subelement'), "Second element", list('F', 'B', 'I', c('phone', 'pad', 'talics')))
> pandoc.list(l, 'roman')

Which returns:


I. First list element 
    I. 1. subelement 
    II. 2. subelement 
    III. 3. subelement 
    IV. 4. subelement 
    V. 5. subelement  
II. Second element 
    I. F 
    II. B 
    III. I 
        I. phone 
        II. pad 
        III. talics   

<!-- end of list -->

Tables

pandoc can return tables in four formats supported by Pandoc, including the pipe tables also used in knitr and PHP Markdown Extra format:

> m <- mtcars[1:2, 1:3]
> pandoc.table(m)

--------------------------------------
      &nbsp;         mpg   cyl   disp 
------------------- ----- ----- ------
   **Mazda RX4**     21     6    160  

 **Mazda RX4 Wag**   21     6    160  
--------------------------------------
> pandoc.table(m, style = "simple")

      &nbsp;         mpg   cyl   disp 
------------------- ----- ----- ------
   **Mazda RX4**     21     6    160  
 **Mazda RX4 Wag**   21     6    160  
> pandoc.table(m, style = "grid")

+---------------------+-------+-------+--------+
|       &nbsp;        |  mpg  |  cyl  |  disp  |
+=====================+=======+=======+========+
|    **Mazda RX4**    |  21   |   6   |  160   |
+---------------------+-------+-------+--------+
|  **Mazda RX4 Wag**  |  21   |   6   |  160   |
+---------------------+-------+-------+--------+
> pandoc.table(m, style = "rmarkdown")

|       &nbsp;        |  mpg  |  cyl  |  disp  |
|:-------------------:|:-----:|:-----:|:------:|
|    **Mazda RX4**    |  21   |   6   |  160   |
|  **Mazda RX4 Wag**  |  21   |   6   |  160   |

Besides the style parameter there are several other ways to tweak the output like decimal.mark or digits. And of course it's really easy to add a caption:

> pandoc.table(m, style = "grid", caption = "Hello caption!")

+---------------------+-------+-------+--------+
|       &nbsp;        |  mpg  |  cyl  |  disp  |
+=====================+=======+=======+========+
|    **Mazda RX4**    |  21   |   6   |  160   |
+---------------------+-------+-------+--------+
|  **Mazda RX4 Wag**  |  21   |   6   |  160   |
+---------------------+-------+-------+--------+

Table: Hello caption!

pandoc.table˙can deal with the problem of really wide tables. Ever had an issue in LaTeX or MS Word when tried to print a correlation matrix of 40 variables? Not a problem any more as pandoc.table splits up the table if wider then 80 characters and handles caption too:

> pandoc.table(mtcars[1:2, ], style = "grid", caption = "Hello caption!")

+---------------------+-------+-------+--------+------+--------+-------+
|       &nbsp;        |  mpg  |  cyl  |  disp  |  hp  |  drat  |  wt   |
+=====================+=======+=======+========+======+========+=======+
|    **Mazda RX4**    |  21   |   6   |  160   | 110  |  3.9   | 2.62  |
+---------------------+-------+-------+--------+------+--------+-------+
|  **Mazda RX4 Wag**  |  21   |   6   |  160   | 110  |  3.9   | 2.875 |
+---------------------+-------+-------+--------+------+--------+-------+

Table: Hello caption! (continued below)

 

+---------------------+--------+------+------+--------+--------+
|       &nbsp;        |  qsec  |  vs  |  am  |  gear  |  carb  |
+=====================+========+======+======+========+========+
|    **Mazda RX4**    | 16.46  |  0   |  1   |   4    |   4    |
+---------------------+--------+------+------+--------+--------+
|  **Mazda RX4 Wag**  | 17.02  |  0   |  1   |   4    |   4    |
+---------------------+--------+------+------+--------+--------+

And too wide cells are also split by line breaks. E.g.:

> pandoc.table(data.frame(id=1:2, value=c('FOO', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.')))

----------------------------------
 id              value            
---- -----------------------------
 1                FOO             

 2    Lorem ipsum dolor sit amet, 
     consectetur adipisicing elit,
         sed do eiusmod tempor    
        incididunt ut labore et   
     dolore magna aliqua. Ut enim 
     ad minim veniam, quis nostrud
     exercitation ullamco laboris 
     nisi ut aliquip ex ea commodo
      consequat. Duis aute irure  
       dolor in reprehenderit in  
      voluptate velit esse cillum 
        dolore eu fugiat nulla    
       pariatur. Excepteur sint   
        occaecat cupidatat non    
      proident, sunt in culpa qui 
     officia deserunt mollit anim 
            id est laborum.       
----------------------------------

Caption

Beside directly calling pandoc.table's caption parameter, one could also set a caption even before printing the markdown format - just use set.caption function:

> set.caption('Hello caption!')
> pandoc.table(mtcars[1:2, ])

--------------------------------------------------------
      &nbsp;         mpg   cyl   disp   hp   drat   wt  
------------------- ----- ----- ------ ---- ------ -----
   **Mazda RX4**     21     6    160   110   3.9   2.62 

 **Mazda RX4 Wag**   21     6    160   110   3.9   2.875
--------------------------------------------------------

Table: Hello caption! (continued below)

 
--------------------------------------------------
      &nbsp;         qsec   vs   am   gear   carb 
------------------- ------ ---- ---- ------ ------
   **Mazda RX4**    16.46   0    1     4      4   

 **Mazda RX4 Wag**  17.02   0    1     4      4   
--------------------------------------------------

Of course the set.caption function is not needed to be called directly before pandoc.table and it can be also used by the pander method or inside of Pandoc.brew documents too.

Cell alignment

One can specify the alignment of the cells in a table directly by setting the justify parameter in pandoc.table:

> panderOptions('table.split.table', Inf)
> pandoc.table(head(iris), justify = 'right')

-------------------------------------------------------------------
  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
-------------------------------------------------------------------

Or pre-define the alignment for pandoc.table or the pander S3 method by a helper function:

> set.alignment('left', row.names = 'right')
> pandoc.table(mtcars[1:2,  1:5])

--------------------------------------------------
             &nbsp; mpg   cyl   disp   hp   drat  
------------------- ----- ----- ------ ---- ------
      **Mazda RX4** 21    6     160    110  3.9   

  **Mazda RX4 Wag** 21    6     160    110  3.9   
--------------------------------------------------

Table: Hello caption!

> set.alignment(c('left', 'right', 'center', 'centre'))
> pandoc.table(iris[1:3, 1:4])

---------------------------------------------------------
Sepal.Length     Sepal.Width  Petal.Length   Petal.Width 
-------------- ------------- -------------- -------------
5.1                      3.5      1.4            0.2     

4.9                        3      1.4            0.2     

4.7                      3.2      1.3            0.2     
---------------------------------------------------------

Beside using set.alignment helper or passing parameters directly to pandoc.table, you may also set the default alignment styles with panderOptions.

And feel free to use either centre or center to align cells to the middle :)

Highlight cells

And IMHO the most important feature in pander is the ease of highlighting rows, columns or any cells in a table that can be exported to HTML/pdf/MS Word etc. with the help of Pandoc.

This can be achieved by calling pandoc.table directly and passing any (or more) of the following arguments:

emphasize would turn the affected cells to italic, while emphasize.strong would apply a bold style in the cell. Of course a cell can be also italic and strong at the same time.

Arguments ending in rows or cols take a vector (e.g. which columns or rows to emphasize in a table), while the cells argument take either a vector (for one dimensional "tables") or an array-like data structure with two columns holding row and column indexes of cells to be emphasized -- just like what which(..., arr.ind = TRUE) returns.

Examples:

```rout > t <- mtcars[1:3, 1:5] > emphasize.cols(1) > emphasize.rows(1) > pandoc.table(t)

  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

``Of course the these helper functions works with [pandermethod](#generic-pander-method) or inside of [Pandoc.brew` documents](#brew-to-pandoc) too:

> emphasize.strong.cells(which(t > 20, arr.ind = TRUE))
> pander(t)

---------------------------------------------------------
      &nbsp;          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 
---------------------------------------------------------

> Pandoc.brew(text='
## Title

<\%\=
set.caption('Formatted table')
emphasize.rows(1)
mtcars[1:2, 1:5]
\%>')

---------------------------------------------------
      &nbsp;         mpg   cyl   disp   hp    drat 
------------------- ----- ----- ------ ----- ------
   **Mazda RX4**    *21*   *6*  *160*  *110* *3.9* 

 **Mazda RX4 Wag**   21     6    160    110   3.9  
---------------------------------------------------

Table: Formatted table

Generic pander method

pander or pandoc (call as you wish) can deal with a bunch of R object types as being a pandocized S3 method with a variety of classes.

Besides simple types (vectors, matrices, tables or data frames) lists might be interesting for you:

> pander(list(a=1, b=2, c=table(mtcars$am), x=list(myname=1,2), 56))

  * **a**: _1_
  * **b**: _2_
  * **c**:

    -------
     0   1
    --- ---
    19  13
    -------

  * **x**:

      * **myname**: _1_
      * _2_

  * _56_

<!-- end of list -->

A nested list can be seen above with a table and all (optional) list names inside. As a matter of fact pander.list is the default method of pander too, see:

> x <- chisq.test(table(mtcars$am, mtcars$gear))
> class(x) <- "I've never heard of!"
> pander(x)
 **WARNING**^[Chi-squared approximation may be incorrect]

  * **statistic**: _20.94_
  * **parameter**: _2_
  * **p.value**: _2.831e-05_
  * **method**: Pearson's Chi-squared test
  * **data.name**: table(mtcars$am, mtcars$gear)
  * **observed**:

    -------------------
    &nbsp;   3   4   5
    ------- --- --- ---
     **0**  15   4   0

     **1**   0   8   5
    -------------------

  * **expected**:

    -------------------------
    &nbsp;    3     4     5
    ------- ----- ----- -----
     **0**  8.906 7.125 2.969

     **1**  6.094 4.875 2.031
    -------------------------

  * **residuals**:

    ----------------------------
    &nbsp;    3      4      5
    ------- ------ ------ ------
     **0**  2.042  -1.171 -1.723

     **1**  -2.469 1.415  2.083
    ----------------------------

  * **stdres**:

    ----------------------------
    &nbsp;    3      4      5
    ------- ------ ------ ------
     **0**  4.395  -2.323 -2.943

     **1**  -4.395 2.323  2.943
    ----------------------------

<!-- end of list -->

So pander showed a not known class in an (almost) user-friendly way. And we got some warnings too styled with Pandoc footnote! If that document is exported to e.g. HTML or pdf, then the error/warning message could be found on the bottom of the page with a link. Note: there were two warnings in the above call - both captured and returned! Well, this is the feature of Pandoc.brew, see below.

The output of different statistical methods are tried to be prettyfied. Some examples:

> pander(ks.test(runif(50), runif(50)))

---------------------------------------------------
 Test statistic   P value   Alternative hypothesis 
---------------- --------- ------------------------
      0.14       _0.7166_         two-sided        
---------------------------------------------------

Table: Two-sample Kolmogorov-Smirnov test: `runif(50)` and `runif(50)`

> pander(chisq.test(table(mtcars$am, mtcars$gear)))

---------------------------------------
 Test statistic   df       P value     
---------------- ---- -----------------
     20.94        2   _2.831e-05_ * * *
---------------------------------------

Table: Pearson's Chi-squared test: `table(mtcars$am, mtcars$gear)`

 **WARNING**^[Chi-squared approximation may be incorrect]

> pander(t.test(extra ~ group, data = sleep))

---------------------------------------------------------
 Test statistic   df    P value   Alternative hypothesis 
---------------- ----- --------- ------------------------
     -1.861      17.78 _0.07939_        two.sided        
---------------------------------------------------------

Table: Welch Two Sample t-test: `extra` by `group`

> ## Dobson (1990) Page 93: Randomized Controlled Trial (examples from: ?glm)
> counts <- c(18,17,15,20,10,20,25,13,12)
> outcome <- gl(3,1,9)
> treatment <- gl(3,3)
> m <- glm(counts ~ outcome + treatment, family=poisson())
> pander(m)

--------------------------------------------------------------
     &nbsp;        Estimate   Std. Error   z value   Pr(>|z|) 
----------------- ---------- ------------ --------- ----------
 **(Intercept)**    3.045       0.1709      17.81   5.427e-71 

  **outcome2**     -0.4543      0.2022     -2.247    0.02465  

  **outcome3**      -0.293      0.1927      -1.52     0.1285  

 **treatment2**   1.338e-15      0.2      6.69e-15      1     

 **treatment3**   1.421e-15      0.2      7.105e-15     1     
--------------------------------------------------------------

Table: Fitting generalized (poisson/log) linear model: counts ~ outcome + treatment

> pander(anova(m))

--------------------------------------------------------
    &nbsp;       Df   Deviance   Resid. Df   Resid. Dev 
--------------- ---- ---------- ----------- ------------
   **NULL**                          8         10.58    

  **outcome**    2     5.452         6         5.129    

 **treatment**   2   2.665e-15       4         5.129    
--------------------------------------------------------

Table: Analysis of Deviance Table

> pander(aov(m))

-----------------------------------------------------------
    &nbsp;       Df   Sum Sq    Mean Sq   F value   Pr(>F) 
--------------- ---- --------- --------- --------- --------
  **outcome**    2     92.67     46.33     2.224    0.2242 

 **treatment**   2   8.382e-31 4.191e-31 2.012e-32    1    

 **Residuals**   4     83.33     20.83                     
-----------------------------------------------------------

Table: Analysis of Variance Model

> pander(prcomp(USArrests))

-------------------------------------------------
    &nbsp;       PC1     PC2      PC3      PC4   
-------------- ------- -------- -------- --------
  **Murder**   0.0417  -0.04482 0.07989  -0.9949 

 **Assault**   0.9952  -0.05876 -0.06757 0.03894 

 **UrbanPop**  0.04634  0.9769  -0.2005  -0.05817

   **Rape**    0.07516  0.2007   0.9741  0.07233 
-------------------------------------------------

Table: Principal Components Analysis

----------------------------------------------------------
           &nbsp;             PC1     PC2    PC3     PC4  
---------------------------- ------ ------- ------ -------
   **Standard deviation**    83.73   14.21  6.489   2.483 

 **Proportion of Variance**  0.9655 0.02782 0.0058 0.00085

 **Cumulative Proportion**   0.9655 0.9933  0.9991    1   
----------------------------------------------------------

> pander(density(mtcars$hp))

--------------------------------------------
   &nbsp;      Coordinates   Density values 
------------- ------------- ----------------
  **Min.**       -32.12          5e-06      

 **1st Qu.**      80.69        0.0004068    

 **Median**       193.5         0.001665    

  **Mean**        193.5         0.002214    

 **3rd Qu.**      306.3         0.00409     

  **Max.**        419.1         0.006051    
--------------------------------------------

Table: Kernel density of *mtcars$hp* (bandwidth: 28.04104)

> ## Don't like scientific notation?
> panderOptions('round', 2)
> pander(density(mtcars$hp))

--------------------------------------------
   &nbsp;      Coordinates   Density values 
------------- ------------- ----------------
  **Min.**       -32.12            0        

 **1st Qu.**      80.69            0        

 **Median**       193.5            0        

  **Mean**        193.5            0        

 **3rd Qu.**      306.3            0        

  **Max.**        419.1           0.01      
--------------------------------------------

Table: Kernel density of *mtcars$hp* (bandwidth: 28.04104)

And of course tables are formatted (e.g. auto add of line breaks and splitting up tables) nicely:

> set.caption('Foo Bar')
> pander(data.frame(id=1:2, value=c('FOO', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.')))

----------------------------------
 id              value            
---- -----------------------------
 1                FOO             

 2    Lorem ipsum dolor sit amet, 
     consectetur adipisicing elit,
         sed do eiusmod tempor    
        incididunt ut labore et   
     dolore magna aliqua. Ut enim 
     ad minim veniam, quis nostrud
     exercitation ullamco laboris 
     nisi ut aliquip ex ea commodo
      consequat. Duis aute irure  
       dolor in reprehenderit in  
      voluptate velit esse cillum 
        dolore eu fugiat nulla    
       pariatur. Excepteur sint   
        occaecat cupidatat non    
      proident, sunt in culpa qui 
     officia deserunt mollit anim 
            id est laborum.       
----------------------------------

Table: Foo Bar

Methods

The list of currently supported R classes:

> methods(pander)
 [1] pander.anova*      pander.aov*        pander.cast_df*    pander.character*
 [5] pander.data.frame* pander.default*    pander.density*    pander.evals*
 [9] pander.factor*     pander.glm*        pander.htest*      pander.image*
[13] pander.list*       pander.lm*         pander.logical*    pander.matrix*
[17] pander.NULL*       pander.numeric*    pander.option      pander.POSIXct*
[21] pander.POSIXt*     pander.prcomp*     pander.rapport*    pander.return
[25] pander.table*

   Non-visible functions are asterisked

Brew to Pandoc

Everyone knows and possibly uses brew but if you would need some smack, the following links really worth visiting:

In short: 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):

This latter tries to be smart in some ways:

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 (and other, from pander package POV needless features) of brew is removed for some extra profits:

This document was generated by Pandoc.brew based on inst/README.brew so the above examples were generated automatically - which could be handy while writing some nifty statistical reports :)

Pandoc.brew(system.file('README.brew', package='pander'))

Pandoc.brew could cook a file (default) or work with a character vector provided in the text argument. The output is set to stdout by default, it could be tweaked to write result to a text file and run Pandoc on that to create a HTML, odt, docx or other document.

To export a brewed file to other then Pandoc's markdown, please use the convert parameter. For example (please disregard the backslash in front of the percent sign):

text <- paste('# Header', '', 'What a lovely list:\n<\%=as.list(runif(10))\%>', 'A wide table:\n<\%=mtcars[1:3, ]\%>', 'And a nice chart:\n\n<\%=plot(1:10)\%>', sep = '\n')
Pandoc.brew(text = text, output = tempfile(), convert = 'html')
Pandoc.brew(text = text, output = tempfile(), convert = 'pdf')

Of course a text file could work as input (by default) the above example uses text parameter as a reproducible example. For example brewing this README with all R chunks and converted to html, please run:

Pandoc.brew(system.file('README.brew', package='pander'), output = tempfile(), convert = 'html')

And there are some package bundled examples too.

Examples

The package comes bundled with some examples for Pandoc.brew to let users check out its features pretty fast. These are:

To brew these examples on your machine try to run the followings.:

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')

For easy access I have uploaded some exported documents of the above examples:

Please check out pdf, docx, odt and other formats (changing the above convert option) on your machine too and do not forget to give some feedback!

Live report generation

pander package has a special reference class called Pandoc which could collect some blocks in a live R session and export the whole document to Pandoc/pdf/HTML etc.

Without any serious comments, please check out the below (self-commenting) example:

## Initialize a new Pandoc object
myReport <- Pandoc$new()

## Add author, title and date of document
myReport$author <- 'Gergely Daróczi'
myReport$title  <- 'Demo'

## Or it could be done while initializing
myReport <- Pandoc$new('Gergely Daróczi', 'Demo')

## Add some free text
myReport$add.paragraph('Hello there, this is a really short tutorial!')

## Add maybe a header for later stuff
myReport$add.paragraph('# Showing some raw R objects below')

## Adding a short matrix
myReport$add(matrix(5,5,5))

## Or a table with even
myReport$add.paragraph('Hello table:')
myReport$add(table(mtcars$am, mtcars$gear))

## Or a "large" data frame which barely fits on a page
myReport$add(mtcars)

## And a simple linear model with Anova tables
ml <- with(lm(mpg ~ hp + wt), data = mtcars)
myReport$add(ml)
myReport$add(anova(ml))
myReport$add(aov(ml))

## And do some principal component analysis at last
myReport$add(prcomp(USArrests))

## Sorry, I did not show how Pandoc deals with plots:
myReport$add(plot(1:10))

## Want to see the report? Just print it:
myReport

## Exporting to pdf (default)
myReport$export()

## Or to docx in tempdir():
myReport$format <- 'docx'
myReport$export(tempfile())

## You do not want to see the generated report after generation?
myReport$export(open = FALSE)

Pander options

pander comes with some globally adjustable options which would have an effect on the result of your reports. You can query and update these options with panderOptions():

Besides localization of numeric formats, table/list's and plots' styles there are some technical options too which would effect e.g. caching or the format of rendered image files. You can query/update those with evalsOptions() as the main backend of pander calls is a custom evaluation function called evals.

The list of possible options are:

Caching

As pander is using a custom caching algorithm, it might be worthwhile to give a short summary of what is going on in the background.

All evaluation of provided R commands (while running brew or "live report generation" is done by evals which is caching results (besides returned informative/warning/error messages, anything written to stdout etc. - see below) line-by-line (to be more accurate: by single R commands) instead of caching chunks without any noticeable overhead.

Theoretical background

In practice

As pander does not cache based on raw sources of chunks and there is no easy way of enabling/disabling caching on a chunk basis, the users have to live with some great advantages and some minor tricky situations - which latter cannot be solved theoretically in my opinion, but I'd love to hear your feedback.

The caching hash is computed based on the structure and content of the R commands, so let us make some POC example to show the greatest asset:

x <- mtcars$hp
y <- 1e3
evals('sapply(rep(x, y), mean)')

It took a while, huh? :)

Let us have some custom functions and variables:

f <- sapply
g <- rep
h <- mean
X <- mtcars$hp * 1
Y <- 1000

And now try to run something like:

evals('f(g(X, Y), h)')

Yes, it was returned from cache!

About the kickback:

As pander (or rather: evals) does not really deal with what is written in the provided sources but rather checks what is inside that, there might be some tricky situations where you would expect the cache to work, but it would not. Short example: we are computing and saving to a variable something heavy in a chunk (please run these in a clean R session to avoid conflicts):

evals('x <- sapply(rep(mtcars$hp, 1e3), mean)')

It is cached, just run again, you will see.

But if you would create x in your global environment with any value (which has nothing to do with the special environment of the report!) and x was not defined in the report before this call (and you had no x value in your global environment before), then the content of x would result in a new hash for the cache - so caching would not work. E.g.:

x <- 'foobar'
evals('x <- sapply(rep(mtcars$hp, 1e3), mean)')

I really think this is a minor issue (with very special coincidences) which cannot be addressed cleverly - but could be avoided with some cautions (e.g. run Pandoc.brew in a clean R session like with Rscript or littler - if you are really afraid of this issue). And after all: you loose nothing, just the cache would not work for that only line and only once in most of the cases.

Other cases when the hash of a call will not match cached hashes:

But the e.g. following do work from cache fine:

x  <- mtcars$hp
xx <- mtcars$hp*1
evals('mean(x)')
evals('mean(xx)')

Evals

Sorry, no online documentation here ATM. Please check: ?evals

Or head to the CRAN version of the docs at help.r-enthusiasts.com

ESS

I have created some simple LISP functions which would be handy if you are using the best damn IDE for R. These functions and default key-bindings are shipped with the package, feel free to personalize.

As time passed these small functions grew heavier (with my Emacs knowledge) so I ended up with a small library:

pander-mode

I am currently working on pander-mode which is a small minor-mode for Emacs. There are a few (but useful) functions with default keybindings:

Few options of pander-mode: M-x customize-group pander

To use this small lib, just type: M-x pander-mode on any document. It might be useful to add a hook to markdown-mode if you find this useful.

githalytics.com alpha


This report was generated with R (3.0.1) and pander (0.3.7) in 1.05 sec on x86_64-unknown-linux-gnu platform.