Gt: Add ability to do formula based on other columns in Summary Rows

Created on 25 Oct 2019  Â·  3Comments  Â·  Source: rstudio/gt

Here's an easy example. I have a gt table where I get the sum of a variety of columns. One of the columns is for % of value. I'd like to get the % of value based on the sums in the Summary/Grand Summary Row as well.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

df <-
  tibble::tribble(
    ~price, ~value,
    5, 4,
    2, 6,
    3, 1
  )


df <-
  df %>%
  mutate(pct_of_value = value / price)

df
#> # A tibble: 3 x 3
#>   price value pct_of_value
#>   <dbl> <dbl>        <dbl>
#> 1     5     4        0.8  
#> 2     2     6        3    
#> 3     3     1        0.333

summary_row <-
  df %>%
  summarise_at(vars(price, value), sum) %>%
  mutate(pct_of_value = value / price)

summary_row
#> # A tibble: 1 x 3
#>   price value pct_of_value
#>   <dbl> <dbl>        <dbl>
#> 1    10    11          1.1
Created on 2019-10-24 by the reprex package (v0.3.0)
[3] Advanced [2] Medium [2] Medium ★ Enhancement

Most helpful comment

Another hack to consider:

df <- tibble::tribble(
    ~price, ~value,
    5, 4,
    2, 6,
    3, 1
  )

df %>% 
  dplyr::mutate(pct_of_value = value / price) %>% 
  gt() %>% 
  summary_rows(fns = list(total = ~ sum(.)), columns = vars(price, value)) %>% 
  (function(x) {
    res <- function() x$`_data` %>% 
      dplyr::summarize(pct_of_value = sum(value) / sum(price)) %>% 
      dplyr::pull(.data$pct_of_value)

    summary_rows(x, fns = list(total = ~ res()), columns = vars(pct_of_value))
  })

All 3 comments

Cosign on this issue. In the meantime, a cheap hack is to overwrite the missing_text attribute within the gt object, e.g.:

library(gt)
library(dplyr)

gt_table <- iris %>% 
  group_by(Species) %>% 
  summarize_all(mean) %>% 
  mutate(
    random_perc1 = rnorm(3),
    random_perc2 = rnorm(3),
    random_perc3 = rnorm(3),
    ) %>% 
  gt(rowname_col = "Species") %>% 
  summary_rows(
    columns = matches("\\."),
    fns = list(Total = ~sum(.))
  )
attributes(gt_table)$summary[[1]]$missing_text <- c("val1", "val2", "val3")
gt_table

Another hack to consider:

df <- tibble::tribble(
    ~price, ~value,
    5, 4,
    2, 6,
    3, 1
  )

df %>% 
  dplyr::mutate(pct_of_value = value / price) %>% 
  gt() %>% 
  summary_rows(fns = list(total = ~ sum(.)), columns = vars(price, value)) %>% 
  (function(x) {
    res <- function() x$`_data` %>% 
      dplyr::summarize(pct_of_value = sum(value) / sum(price)) %>% 
      dplyr::pull(.data$pct_of_value)

    summary_rows(x, fns = list(total = ~ res()), columns = vars(pct_of_value))
  })

Add another hack with grouping, from https://github.com/rstudio/gt/issues/383#issuecomment-584212376 :

df <- tibble::tribble(
  ~group, ~price, ~value,
  "a", 5, 4,
  "a", 2, 6,
  "b", 3, 1
)

df %>%
  dplyr::mutate(pct_of_value = value / price) %>% 
  gt(groupname_col = "group") %>% 
  # row_group_order(groups = c("b","a")) %>%
  summary_rows(groups = TRUE, fns = list(total = ~ sum(.)), columns = c(price, value)) %>% 
  (function(x) {
    res <- function(gid) {
      g <- gid[[1]]
      x$`_data` %>% filter(group==g) %>%
        summarize(pct_of_value = sum(value) / sum(price)) %>%
        pull(pct_of_value)
    }
    summary_rows(x, groups = TRUE, fns = list(total = ~ res(cur_group())), columns = c(pct_of_value))
  })
Was this page helpful?
0 / 5 - 0 ratings

Related issues

rich-iannone picture rich-iannone  Â·  4Comments

Torvaney picture Torvaney  Â·  3Comments

steveputman picture steveputman  Â·  3Comments

tbradley1013 picture tbradley1013  Â·  3Comments

higgi13425 picture higgi13425  Â·  4Comments