How to write multi-level (bullet) lists in a table using rmarkdown and pandoc

2.2k views Asked by At

I am looking to create a table in a PDF document using rmarkdown, knitr and pander. I am able to create a simple bullet list but now require another level in that list. In the table shown below, I require the "Rave reviews" bullet to be a sub-bullet of the "Offers workshops..." bullet.

multibullet

The issue I'm having pertains to the line of code below in the mytable dataframe in the Description column. Although I attempt to create the 4 spaces required for a sub-bullet using \x20[1], those spaces do not appear - and hence no sub-bullets (although no error is shown). I also tried the most obvious way of simply adding in 4 spaces in the code to no avail. Also attempted to set my R options to include strip.white = FALSE, but that has also not proven helpful (see below).

---
title: "xxx"
author: "xxx"
output:
  pdf_document:
    fig_height: 4
    fig_width: 10
    highlight: tango
  word_document: default
geometry: margin=3cm
---

```{r global_options, include=FALSE, echo=FALSE}
require(knitr)
opts_chunk$set(fig.width=8, fig.height=4, fig.path='figs/', dpi=500,
               echo=FALSE, warning=FALSE, message=FALSE, results='hide', strip.white = FALSE)
```

```{r pandoc_options, include=FALSE, echo=FALSE}
require(pander)
panderOptions('digits', 3)
panderOptions('round', 3)
panderOptions('keep.trailing.zeros', TRUE)
panderOptions('keep.line.breaks', TRUE)
```

```{r concepts, echo=FALSE}
mytable = data.frame(
    Concept     = c("Decoded", "XXX"),
    Description = c("* Founded in 2011\ \n* Offers workshops to take people from zero skills and knowledge in programming through to coding a multi-platform app using HTML, CSS and Javascript in a single day\ \n\x20\x20\x20\x20+ Rave reviews", "XXX"),
    Website     = c("http://decoded.com/uk/","XXX"))
```

``` {r concepts_descriptions, results = 'asis'}
pander::pander(mytable, keep.line.breaks = TRUE, style = 'grid', justify = 'left')
```

References

[1] I got the \x20 hint from here, after attempting \\s, \s, \ \s, \\\s, etc. to no avail (suggested here).

2

There are 2 answers

0
bergant On BEST ANSWER

You can nest the items inside the bullet:

```{r concepts, echo=FALSE}
mytable = data.frame(
    Concept     = c("Decoded", "XXX"),
    Description = c("* Founded in 2011\ \n
    * Offers workshops to take people from zero skills and knowledge in programming through to coding a multi-platform app using HTML, CSS and Javascript in a single day\ \n
    \\begin{itemize}
      \\item Rave reviews \n
      \\item e.t.c
    \\end{itemize}", "XXX"),
    Website     = c("http://decoded.com/uk/","XXX"))
```
0
rawr On

Edit: I didn't realize you were using a pdf, but here is an html solution

  1. I would use a matrix
  2. I would use the htmlTable package which allows for much more advanced tables than kable or pander

First make a wrapper for your lists

make_list <- function(...) {
  paste0("<ul>", sprintf('<li>%s</li>', substitute(...())), '</ul>', collapse = '')
}

make_list(one, two, three)

# [1] "<ul><li>one</li></ul><ul><li>two</li></ul><ul><li>three</li></ul>"


library('htmlTable')
mytable <- matrix(c("Decoded", "XXX",
                    make_list('Founded in 2011', 'Offers workshops to take people from zero skills and knowledge in programming through to coding a multi-platform app using HTML, CSS and Javascript in a single day','Rave reviews'),
                    "XXX",
                    "http://decoded.com/uk/","XXX"), 2,
                  dimnames = list(NULL, c('Concept','Description','Website')))

htmlTable(mytable, align = 'lll')

enter image description here

This is fine but the vertical align is bad and the boxes are too wide. But we can fix with one of the css parameters of htmlTable. vertical align pushes the text to the top rather than center, max-width sets the text wrapping, and auto width lets each have its own width

htmlTable(mytable, align = 'lll', align.header = 'lll',
          css.cell = "width: auto; max-width: 250px; vertical-align: top;")

enter image description here