For presentation purposes I often have to format a data frame with column and row totals and percentages.
Piping the row totals and percentages conditionally is straight forward: stackoverflow e.g.
The column totals can be neatly piped:
option 1: stackoverflow e.g.
option 2: using the janitor package function adorn_totals
(however I'd prefer to find a way without adding more packages to my workflow).
I get stuck on the next step which is to add a column % row below the column total. This row calculates the column sum (column total) as a percentage of table sum (table total).
Here I have to split my workflow to do the following:
- create a table total variable
- function to calculate the percentage of a vector
- calculate the column percentage row
- bind the column percentage row to the table
This process feels heavy handed and I am sure there is a better way; suggestions welcome.
This is what I am aiming to achieve
Once the table is generated formatting and tidying up for presentation purposes I usually do with flextable or kableExtra as a second pass.
MWE
library(tidyverse)
tib <- tibble(v1 = c("a", "b", "c"),
v2 = 1:3,
v3 = 4:6)
# piping row summaries and column totals
tib <-
tib %>%
mutate(r_sum = rowSums(.[2:3]),
r_pc = r_sum * 100/sum(r_sum)) %>%
bind_rows(summarise_all(., funs(if(is.numeric(.)) sum(.) else "Total")))
# extract gross total
table_total <- tib$r_sum[4]
# function to calculate percentage * 2 as tib includes a column total row
calc_pc <- function(x) {sum(x) * 100 / (table_total * 2)}
# calculate column percentages
col_pc <-
tib %>%
summarise_at(vars(v1:r_sum), funs(if(is.numeric(.)) calc_pc(.) else "Column %"))
# finally bringing it all together for the desired result
tib <-
tib %>%
bind_rows(col_pc)