relabeling columns with a function

How can I rename/relabel multiple columns of a gt table with a function? E.g. in the case below I want to display only the year numbers and remove the characters. Is this currently not possible via cols_label? Many thanks!

PS: I see that the table is not entirely correct displayed in the reprex. There are two spanners, and below each three columns with the year numbers.

library(tidyverse)
#> Warning: package 'tidyverse' was built under R version 3.6.3
#> Warning: package 'ggplot2' was built under R version 3.6.3
#> Warning: package 'purrr' was built under R version 3.6.3
#> Warning: package 'dplyr' was built under R version 3.6.3
#> Warning: package 'forcats' was built under R version 3.6.3
library(gt)
#> Warning: package 'gt' was built under R version 3.6.3

my_table <- data.frame(
  stringsAsFactors = FALSE,
                id = c("a", "b", "c"),
            n_2010 = c(1L, 2L, 3L),
            n_2011 = c(1L, 2L, 3L),
            n_2012 = c(1L, 2L, 3L),
          rel_2010 = c(1L, 2L, 3L),
          rel_2011 = c(1L, 2L, 3L),
          rel_2012 = c(1L, 2L, 3L)
)

gt(my_table) %>% 
  tab_spanner(label="absolute",
              columns=starts_with("n_")) %>% 
  tab_spanner(label="relative",
              columns=starts_with("rel_")) 

id

absolute

relative

n_2010

n_2011

n_2012

rel_2010

rel_2011

rel_2012

a

1

1

1

1

1

1

b

2

2

2

2

2

2

c

3

3

3

3

3

3


#attempts which don't work

#function
gt(my_table) %>% 
  tab_spanner(label="absolute",
              columns=starts_with("n_")) %>% 
  tab_spanner(label="relative",
              columns=starts_with("rel_")) %>% 
  cols_label(.list = function(x) str_extract_all(., "\\d"))
#> Error: Named arguments are required for `cols_label()`.

#text_transform
gt(my_table) %>% 
  tab_spanner(label="absolute",
              columns=starts_with("n_")) %>% 
  tab_spanner(label="relative",
              columns=starts_with("rel_")) %>% 
  text_transform(locations=cells_column_labels(
  columns=starts_with("n_")),
  fn=function(x) {str_extract_all(x, "\\d")}) #%>%
#> Error: `starts_with()` must be used within a *selecting* function.
#> i See <https://tidyselect.r-lib.org/reference/faq-selection-context.html>.

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

Yes, it works with cols_label(), here is first a manual verification:

gt(my_table) %>% 
  tab_spanner(label="absolute",
              columns=starts_with("n_")) %>% 
  tab_spanner(label="relative",
              columns=starts_with("rel_")) %>%
  cols_label(n_2010 = "2010",
             rel_2010 = "2010",
             n_2011 = "2011",
             rel_2011 = "2011",
             n_2012 = "2012",
             rel_2012 = "2012")

Then you seem to want to do that automatically for all columns, so as the error message suggests, you need an object with names. Let's build a character vector:

years <- as.character(2010:2012)
existing_cols <- c(paste0("n_", years),
                   paste0("rel_",years))
named_years <- set_names(rep(years,2), existing_cols)

And we just have to give that to cols_label(), note that you can't give it in ..., you have to check ?cols_label to find the right argument:

gt(my_table) %>% 
  tab_spanner(label="absolute",
              columns=starts_with("n_")) %>% 
  tab_spanner(label="relative",
              columns=starts_with("rel_")) %>%
  cols_label(.list = named_years)

image