I frequently have to deal with pivot tables and want I way add a total row.
For practicality I prefer to stay within the tidyverse, i.e. not load additional packages (like janitor that has a total function).
Making things a little more tricky, frequently the pivot tables contain missing values (NA).
I calculate the pivot table from larger data frames mainly using the group_by
, count
and pivot_wider
functions.
This sample data frames mimic a such a pivot table:
df <- tribble(~category, ~value1, ~value2,
"cat1", 12, 6,
"cat2", 8, 2,
"cat3", 1, NA,
"cat4", NA, 6) |>
mutate(across(where(is.numeric), as.integer)) # mutate column type to mimic pivot table structure
However, this is just for demonstration - I would like to attach the code to produce a total row directly after group_by
, count
and pivot_wider
.
On stackoverflow I found this solution to make attach a total row...
bind_rows(summarise(.,
across(where(is.numeric), sum),
across(where(is.character), ~"Total")))
... but it doesn't work - neither the summarise
part, nor the bind_rows
part.
I modified it make summarizing possible:
df |>
summarise(across(where(is.character), ~"Total"),
across(where(is.numeric), ~sum(., na.rm = T)))
# works to summarise all columns
Combining summarise
and bind_rows
to attach the totals directly to the data is not possible, an error message related to across
is returned:
df |>
bind_rows(summarise(across(where(is.character), ~"Total")),
across(where(is.numeric), sum(na.rm = TRUE)))
# Error: `across()` must only be used inside dplyr verbs.
How can this problem be solved?
In addition, when combining the summary functions directly after pivoting the original data frame, I also get an error message that the df contains grouped data - which I find strange, since in my understanding it should only use the pivoted data as a source.