Making Pretty Tables in RMarkdown

Why?

Default tables are not that pretty when compiled:

tipjoke <- read.csv('https://uoepsy.github.io/data/TipJoke.csv')
tiptable <- table(tipjoke$Card, tipjoke$Tip)
tiptable
      
        0  1
  Ad   60 14
  Joke 42 30
  None 49 16

The output of table() (above) can sometimes look neat enough, but data in other formats is hard to make look nice (it will just get printed as the object it is, e.g. a tibble below)

library(tidyverse)
pass_scores <- read.csv("https://edin.ac/2wJgYwL") 
pass_scores %>% group_by(school) %>%
  summarise(
    meanPASS = mean(PASS),
    sdPASS = sd(PASS)
  )
# A tibble: 7 × 3
  school      meanPASS sdPASS
  <chr>          <dbl>  <dbl>
1 ECA             32.3   8.02
2 Economics       34     1.41
3 GeoSciences     31    NA   
4 LAW             30.7   1.75
5 PPLS            28.8   1.30
6 SLLC            28    NA   
7 SSPS            31     0   

Functions for pretty tables

kable()

knitr’s kable() is a fairly simple way to make tables and data look a little nicer. Simply pass something to kable() and will usually spit out something nicer. You can find a guide here: https://bookdown.org/yihui/rmarkdown-cookbook/kable.html
We can also add captions to our table!

library(knitr)
kable(tiptable, caption = "Oh what a lovely table")
Table 1: Oh what a lovely table
0 1
Ad 60 14
Joke 42 30
None 49 16

The kable() function also has various useful bits of functionality such as rounding all numeric values to the same number of digits, or setting a value for which all NAs will be displayed.

options(knitr.kable.NA = "")

pass_scores %>% group_by(school) %>%
  summarise(
    meanPASS = mean(PASS),
    sdPASS = sd(PASS)
  ) %>% kable(., digits = 1)
school meanPASS sdPASS
ECA 32.3 8.0
Economics 34.0 1.4
GeoSciences 31.0
LAW 30.7 1.8
PPLS 28.8 1.3
SLLC 28.0
SSPS 31.0 0.0

gt()

The gt package has a lot of useful functionality, and works well with grouped data. The best resource for this is at https://gt.rstudio.com. gt() also allows us to specify captions.

library(tidyverse)
library(gt)
tipjoke %>% 
  count(Card, Tip) %>%
  gt(caption = "Another lovely table!")
Table 2: Another lovely table!
Card Tip n
Ad 0 60
Ad 1 14
Joke 0 42
Joke 1 30
None 0 49
None 1 16

You can shape your data in different ways before passing it to gt().

tipjoke %>% 
  group_by(Card) %>%
  summarise(
    TipYes = sum(Tip==1),
    TipNo = sum(Tip==0)
  ) %>%
  gt()
Card TipYes TipNo
Ad 14 60
Joke 30 42
None 16 49
pass_scores %>% group_by(school) %>%
  summarise(
    meanPASS = mean(PASS),
    sdPASS = sd(PASS)
  ) %>% gt()
school meanPASS sdPASS
ECA 32.33333 8.020806
Economics 34.00000 1.414214
GeoSciences 31.00000 NA
LAW 30.66667 1.751190
PPLS 28.80000 1.303840
SLLC 28.00000 NA
SSPS 31.00000 0.000000

pander()

Pander is nice and simple, and works on the idea of converting R output into neat markdown syntax, which then get compiled into nice looking tables.
You can read up on some of the functionality here: https://cran.r-project.org/web/packages/pander/vignettes/pander.html

library(pander)
pander(tiptable)
  0 1
Ad 60 14
Joke 42 30
None 49 16
pass_scores %>% group_by(school) %>%
  summarise(
    meanPASS = mean(PASS),
    sdPASS = sd(PASS)
  ) %>% pander()
school meanPASS sdPASS
ECA 32.33 8.021
Economics 34 1.414
GeoSciences 31 NA
LAW 30.67 1.751
PPLS 28.8 1.304
SLLC 28 NA
SSPS 31 0