Minimal one-way and two-way summary tables using in R

infoart.ca
3 min readJan 1, 2024

--

Photo by Isabela Kronemberger on Unsplash

Summary tables are essential for exploring and presenting data in a concise and informative manner. In R, packages like gtsummary,janitor andsjPlot provide super user-friendly syntax to create visually appealing summary tables. In this blogpost, we will see how to use them to generate beautiful one-way and two-way summary tables.

Let's load the packages:

library(janitor) #for the tabyl function
library(sjPlot) #for the tab_xtab function
library(gtsummary) #for the tbl_cross function

One-Way Summary Table:

A one-way summary table displays the distribution of a single variable. Here is how to make one using the janitor package (data from diamonds dataset):

diamonds   %>% tabyl(cut) %>% flextable()

Two-Way (crosstabulation) tables using sjPlot:

A two-way table displays the distribution of a variable by the categories of another. Here is how to make one using the tabyl function from the janitor package:

diamonds %>% tabyl(cut, color, show_na = FALSE) %>%
adorn_percentages("row") %>%
adorn_pct_formatting(digits = 2) %>%
adorn_ns() %>% flextable()

And another using the tab_xtab from sjPlot

  
library(sjPlot)

sjPlot::tab_xtab(var.row = diamonds$cut, var.col = diamonds$color,
title = "Table Title", show.row.prc = TRUE)

A beautiful summary table that displays both freq and percentage distribution along with a bunch of independence tests.

Next, we will make a two-way table calculating the row percentage with gtsummary package:

diamonds %>% 
select(cut,color) %>%
tbl_cross(row = cut,
col = color,
percent = "cell",
missing = "no")

Lastly, we will repeat the process to make multiple two-way tables using a loop as requested by a friend:

vars <- c("carat", "cut" ) # select the target row vars

table_list <- list()

for(var in vars) {
tbl <- diamonds %>%
select(color, {{ var }}) %>% #remember to select the col var
tbl_cross(
row = {{ var }},
col = color,
percent = "cell",
missing = "no" )
table_name <- paste0("table_", var)
table_list[[table_name]] <- tbl
}
Print the table list:

> table_list
$table_carat
$table_cut

Now we can view the first table:

(output omitted to screenshot space constraints)

print(table_list[["table_carat"]])

And the second one:

print(table_list[["table_cut"]])

Really cool aren’t they? Must be good enough for making journal articles or professional reports.

Happy tabulating, and a happy new year from infoart!

--

--

infoart.ca
infoart.ca

Written by infoart.ca

Center for Social Capital & Environmental Research | Posts by Bishwajit Ghose, BI consultant and lecturer at the University of Ottawa

No responses yet