2

Given an n by m tibble with numeric values. How do you calculate row and column totals for the tibble.

Here is a reprex with a sample tibble:

library(tidyverse)
df <- tibble(names=c('a','b','c','d','e'),x = 1:5, y =5:1, z=2:6)
df
#> # A tibble: 5 x 4
#>   names     x     y     z
#>   <chr> <int> <int> <int>
#> 1 a         1     5     2
#> 2 b         2     4     3
#> 3 c         3     3     4
#> 4 d         4     2     5
#> 5 e         5     1     6

Created on 2020-06-09 by the reprex package (v0.3.0)

Given this tibble I would like efficiently use tidyverse functions to achieve the following output:

enter image description here

I have been able to accomplish this with a combination of gathers and spreads and joins, but I'm still fairly new to R and the tidyverse and wanted to see if there was a more efficient way to accomplish this.

Community
  • 1
  • 1
Mutuelinvestor
  • 3,384
  • 10
  • 44
  • 75

2 Answers2

3

janitor library has adorn_totals function for this :

library(janitor)
df %>%
  adorn_totals(name = 'col_sum') %>%
  adorn_totals(name = 'row_sum', where = 'col')


#   names  x  y  z row_sum
#       a  1  5  2       8
#       b  2  4  3       9
#       c  3  3  4      10
#       d  4  2  5      11
#       e  5  1  6      12
# col_sum 15 15 20      50
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
2

A solution with bind_rows and bind_cols:

library(tidyverse)
df %>% 
  bind_cols(
    df %>% rowwise() %>% summarise(row_sum = sum(c_across(is.numeric)))
  ) %>% 
  bind_rows(
    df %>% summarise(across(is.numeric, sum))
  ) %>% 
  mutate(names = if_else(is.na(names), "col_sum", names))

# A tibble: 6 x 5
  names       x     y     z row_sum
  <chr>   <int> <int> <int>   <int>
1 a           1     5     2       8
2 b           2     4     3       9
3 c           3     3     4      10
4 d           4     2     5      11
5 e           5     1     6      12
6 col_sum    15    15    20      NA
Ahorn
  • 3,686
  • 1
  • 10
  • 17