Is there a way to create spanners for an arbitrary number of columns?

I would like to create a workflow to create tables using {gt}, Unfortunately, I won't always know how many columns there will be or what their names will be. They will however, follow a consistent pattern as seen below. Obviously, the trailing pipe is an issue in this instance. Is there any easier way to go about this?

library(dplyr)
library(stringr)
library(tidyr)
library(glue)
library(gt)

x <- tibble(
  'A: Expected' = c(1, 2, 6),
  'A: Collected' = c(1, 1, 6),
  'A: Percent' = c(100, 50, 100),
  'B: Expected' = c(2, 4, 9),
  'B: Collected' =  c(1, 1, 9),
  'B: Percent' = c(50, 25, 100)
)

spanners <- function(gt_data = x) {
  y <- names(gt_data)
  
  df <- y %>% 
    tibble() %>% 
    rename(label = 1) %>% 
    filter(str_detect(label, "Expected")) %>% 
    mutate(label = str_replace_all(label, ": Expected", "")) %>% 
    mutate(columns_out = glue("c('{label}: Collected', '{label}: Expected', '{label}: Percent')"))
  
  add_spanners <- df %>% 
    mutate(spanner = glue("tab_spanner(
      label = {label},
      columns = {columns_out},
      id = {label},
      gather = TRUE
    ) %>% "))
  
  return(add_spanners$spanner)
}

t <- x %>% 
  gt() %>%
  spanners()
#> tab_spanner(
#>   label = A,
#>   columns = c('A: Collected', 'A: Expected', 'A: Percent'),
#>   id = A,
#>   gather = TRUE
#> ) %>% 
#> tab_spanner(
#>   label = B,
#>   columns = c('B: Collected', 'B: Expected', 'B: Percent'),
#>   id = B,
#>   gather = TRUE
#> ) %>%

I'd like for it to look like this:

Created on 2021-08-30 by the reprex package (v2.0.1)</sup

I think this does what you want (?)

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
library(stringr)
library(tidyr)
library(glue)
#> 
#> Attaching package: 'glue'
#> The following object is masked from 'package:dplyr':
#> 
#>     collapse
library(gt)

x <- tibble(
  'A: Expected' = c(1, 2, 6),
  'A: Collected' = c(1, 1, 6),
  'A: Percent' = c(100, 50, 100),
  'B: Expected' = c(2, 4, 9),
  'B: Collected' =  c(1, 1, 9),
  'B: Percent' = c(50, 25, 100),
  'C: Expected' = c(2, 4, 9),
  'C: Collected' =  c(1, 1, 9),
  'C: Percent' = c(50, 25, 100)
)

spanners <- function(gt_data = x) {
  y <- names(gt_data)
  
  df <- y %>% 
    tibble() %>% 
    rename(label = 1) %>% 
    filter(str_detect(label, "Expected")) %>% 
    mutate(label = str_replace_all(label, ": Expected", "")) %>% 
    mutate(columns_out = glue("c('{label}: Collected', '{label}: Expected', '{label}: Percent')"))
  
  add_spanners <- df %>% 
    mutate(spanner = glue("tab_spanner(
      label = '{label}',
      columns = {columns_out},
      id = '{label}',
      gather = TRUE
    )"))
  
  ret = glue_collapse(add_spanners$spanner,sep=' %>% ')
  
  return(ret)
}

t <- paste("x %>% gt() %>% ",spanners(x) ) 
t1 <- eval(parse(text = t))
# print(t1)
Created on 2021-08-31 by the reprex package (v2.0.0)

1 Like

I tried glue_collapse, but didn’t use parse. I still don’t fully grok it, but, thank you!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.