Search code examples
rggplot2dtkableextra

How do I create a table in R with conditional formatting and row and column totals?


Are there any R packages that I use to replicate the table below - enter image description here

I would like a table with conditional formatting for the table values but no conditional formatting on the row and column grand totals.

The code can be used to reproduce the values in the table along with the row and column grand totals -

library(tidyverse)

# vectors
dates <- rep(date_vec <- c(as.Date("2022-01-01"), as.Date("2022-02-01"), as.Date("2022-03-01")), 30)
row_groups <- c(rep("row_group1", 20), rep("row_group2", 30), rep("row_group3", 10), rep("row_group4", 30))
col_groups <- c(rep("col_group1", 10), rep("col_group2", 10), rep("col_group3", 30), rep("col_group4", 40))


# dataframe
df <- tibble(dates, row_groups, col_groups)

# column grand totals
col_group_total <- df %>% 
    group_by(dates, col_groups) %>% 
    count() %>% 
    group_by(col_groups) %>% 
    summarise(mean = mean(n)) %>% 
    mutate(pct = mean/sum(mean))

# row grand totals
row_group_total <- df %>% 
    group_by(dates, row_groups) %>% 
    count() %>% 
    group_by(row_groups) %>% 
    summarise(mean = mean(n)) %>% 
    mutate(pct = mean/sum(mean))%>% 
    ungroup()

# table values
group_total <- df %>% 
    group_by(dates, row_groups, col_groups) %>% 
    count() %>% 
    group_by(row_groups, col_groups) %>% 
    summarise(count = mean(n)) %>% 
    ungroup() %>% 
    mutate(pct = count/sum(count))%>% 
    ungroup()

red_color <- "#f4cccc"
yellow_color <- "#f3f0ce"
green_color <- "#d9ead3"



Solution

  • library(janitor); library(gt)
    df %>%
      tabyl(row_groups, col_groups) %>%
      adorn_percentages("all") %>%
      adorn_totals(c("col")) -> df_tabyl
      
    gt(df_tabyl) %>%
      data_color(columns = col_group1:col_group4,
                 colors = scales::col_numeric(
                   palette = c(red_color, yellow_color, green_color),
                   domain = range(df_tabyl[1:4,2:5])
                   )
                 ) %>%
      fmt_percent(columns = -row_groups, 
                  rows = everything()) %>%
      summary_rows(
        columns = -row_groups,
        fns = list("Total" = "sum"),
        formatter = fmt_percent
      ) 
    

    enter image description here

    The coloring varies with your example b/c the col_numeric function maps the colors linearly along the three provided colors, and 11% is only 1/3 of the way between 0% and 33%. Not sure what approach you expect.