knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 7, fig.align = "center" )
suppressPackageStartupMessages(library(tidyverse))

Tables in R Markdown

One of the things that we do over and over is iterate "Table 1" in a paper. One of the most annoying parts of this is that as it gets discovered that patients have exclusion conditions, incomplete data, etc., the Table has to be iterated over and over again, and re-checked, over and over again.

R markdown has some nice components in it for making minimal tables, and has some even nicer components for making demographic tables like Table 1. Tables are so fundamental to statistics, that there are many different packages out there to create them.

Here's a simple example of how the table function can be used. In this little snippet, the first 3 rows and 4 columns of the iris dataset are printed. If you examine the code chunk, it calls results = "asis" in order to specify that the output of the r code is rendered directly to markdown.

Here is what the r commands write back to the console:

pander::pandoc.table(iris[1:3, 1:4])

And here is how it ends up in the markdown document:

pander::pandoc.table(iris[1:3, 1:4])

Almost publication-ready frequency tables

The main use of tables is to display frequency information. Here's an example of how to do it using tabyl from the janitor package.

starwars %>% filter(species == "Human") %>% janitor::tabyl(gender,eye_color) %>% pander::pandoc.table()

Note that with tabyl, you can "adorn" with row and column features using the pipe operator. All that this really does is calculate column totals on the tabyl; you can do similar operations directly on the columns if you'd like.

starwars %>% filter(species == "Human") %>% janitor::tabyl(gender,eye_color) %>%
  janitor::adorn_totals(c("row","col")) %>%
  pander::pandoc.table()

This is great progress, but is still not publication-ready. To make it so, some text formatting would help. One way to do this is to change the case (and name) of the variables going into the table. Since we don't want to keep this data, we can do it as a one-time change with mutate statements. (Remember that this still requires the results = "asis" flag in the code chunk to work.)

starwars %>%
  filter(species == "Human") %>%
  mutate(Gender = stringr::str_to_title(gender)) %>% 
  mutate(`Eye Color` = stringr::str_to_title(eye_color)) %>% 
  janitor::tabyl(Gender, `Eye Color`) %>%
  janitor::adorn_totals(c("row","col")) %>%
  pander::pandoc.table()

The other thing to be aware of is that this is just a data frame-type object. So we can save it to the workspace:

starwars %>%
  filter(species == "Human") %>%
  mutate(Gender = stringr::str_to_title(gender)) %>% 
  mutate(`Eye Color` = stringr::str_to_title(eye_color)) %>% 
  janitor::tabyl(Gender, `Eye Color`) %>%
  janitor::adorn_totals(c("row","col")) -> eyeTable
eyeTable

Now we can edit the object directly if we'd like, to append continuous variables as necessary.



jlucasmckay/JLmisc documentation built on Dec. 14, 2019, 9:33 p.m.