Search code examples
rpurrrgtquosure

Use pwalk to create multiple gt tables from tibble with different tab_styles inputs


I want to create and save several gt tables with pwalk function. I'm using the core code below where the big issue faced is in relation to especifico parameter:

pwalk(tibble(filtro = list(c("Agropecuária", "Indústria", "Serviços", "PIB (pm)", sub_demanda, "Valor Adicionado (pb)", "Impostos (líq. s/ prod.)"), c("Indústria", sub_industria), c("Serviços", sub_servicos)),
                
                titulo = c("**Tabela 1. Variação do PIB (%)**", "**Tabela 2. Variação do PIB na Indústria (%)**", "**Tabela 3. Variação do PIB nos Serviços (%)**"),
               
                especifico = list(quos(style = list(cell_borders(sides = c("top"), color = "black", weight = px(2.5), style = "solid"),
                                                    cell_text(weight = "bold")),
                                       locations = list(cells_body(rows = 4), cells_stub(rows = 9:11))), 
                 
                                  quos(style = cell_borders(sides = c("bottom"), color = "black", weight = px(2.5), style = "solid"),
                                       locations = list(cells_body(rows = 1), cells_stub(rows = 1))),
                 
                                  quos(style = cell_borders(sides = c("bottom"), color = "black", weight = px(2.5), style = "solid"),
                                       locations = list(cells_body(rows = 1), cells_stub(rows = 1)))),
                
               save = c("PIB", "PIB_Industria", "PIB_Serviços")
               ), 
        function(filtro, titulo, especifico, save) {
          
          pib_tri %>% 
            filter(setores_e_subsetores %in% filtro,
                   variavel != "Número-índice") %>% 
            pivot_wider(names_from = "variavel", values_from = "valor") %>% 
            arrange(setores_e_subsetores) %>% 
            
            gt(rowname_col = "setores_e_subsetores", groupname_col = NA) %>%
            cols_hide(c(mes, trimestre)) %>% 
            tab_header(title = md(titulo),
                       subtitle = md(unique(.$`_data`$trimestre))) %>% 
            tab_source_note(source_note = md("Fonte: IBGE. Elaboração própria.")) %>%
            tab_spanner(label = "QoQ (SA)",
                        columns = c(QoQ, `QoQ Anualizado`)) %>% 
            
            tab_style(style = cell_text(weight = "bold"),
                      locations = cells_body(columns = 5)) %>%
            
            tab_style(style = cell_text(color = "black"),
                      locations = cells_body()) %>%
            
            tab_style(style = cell_text(color = "darkgrey", font = google_font("Source Sans Pro")), 
                      locations = cells_column_labels(everything())) %>% 
            
            tab_style(!!especifico) %>% 
            
            opt_table_font(font = list(google_font("Lato"), default_fonts())) %>% 
            
            tab_options(heading.title.font.size = 25,
                        heading.subtitle.font.size = 22,
                        heading.align = "left",
                        
                        table.border.top.style = "hidden",
                        heading.border.bottom.style = "hidden",
                        
                        table.font.size = 20,
                        
                        source_notes.border.bottom.style = "hidden",
                        source_notes.padding = px(10),
                        
                        data_row.padding = px(10)) %>%
            fmt_number(decimals = 2) %>% 
            cols_align("center") %>%
            cols_width(stub() ~ px(300),
                       everything() ~ px(130)) %>% 
            gtsave(paste0(save, ".png")) 
          
        })

Basically I'm trying to pass the parameters of the tab_style function that are specific of each individual table. But the following error message occurs:

Error in `pmap()`:
ℹ In index: 1.
Caused by error in `as_locations()`:
! missing "locals" argument, no default 

The pwalk itself without this part works fine. I've worked with quos() before but unfortunately I'm not so advanced in this topic. What am I missing? Thanks in advance!

Reproducible data:

structure(list(mes = structure(c(19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 19509, 
19509, 19509), class = "Date"), trimestre = c("2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023", "2º trimestre 2023", 
"2º trimestre 2023", "2º trimestre 2023"), setores_e_subsetores = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 
3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 
6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 
9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 
11L, 11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 
13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L, 20L, 20L, 20L, 20L, 20L, 
20L, 22L, 22L, 22L, 22L, 22L, 22L, 15L, 15L, 15L, 15L, 15L, 15L, 
16L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 
18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 19L, 21L, 21L, 
21L, 21L, 21L, 21L), levels = c("Agropecuária", "Indústria", 
"Indústrias extrativas", "Indústrias de transformação", "Eletricidade e gás, água, esgoto, atividades de gestão de resíduos", 
"Construção", "Serviços", "Comércio", "Transporte, armazenagem e correio", 
"Informação e comunicação", "Atividades financeiras, de seguros e serviços relacionados", 
"Atividades imobiliárias", "Outras atividades de serviços", 
"Administração, saúde e educação públicas e seguridade social", 
"Consumo das Famílias", "Consumo do Governo", "FBCF", "Exportação", 
"Importação (-)", "Valor Adicionado (pb)", "Impostos (líq. s/ prod.)", 
"PIB (pm)"), class = "factor"), variavel = c("Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD", "Número-índice", 
"QoQ", "QoQ Anualizado", "YoY", "12m", "YTD"), valor = c(274.76, 
-0.890956967139211, -3.51648187758873, 17, 11.2, 17.9, 138.23, 
0.89044595285015, 3.60964049147785, 1.5, 2.2, 1.7, 237.02, 1.84333777338548, 
7.57974167468622, 8.8, 3.5, 8.2, 114.47, 0.341865357643756, 1.37448974138414, 
-1.7, 0, -1.3, 212.27, 0.449555176982774, 1.81038308221939, 4.8, 
8.1, 5.6, 148.06, 0.721088435374151, 2.91570210107968, 0.3, 2.9, 
0.9, 192.2, 0.612469245668223, 2.47247613743693, 2.3, 3.3, 2.6, 
162.02, 0.0555795714197505, 0.222503699690191, 0.1, 1.5, 0.9, 
179.22, 0.895119067725059, 3.62883808302379, 3.4, 5.6, 4.2, 407.74, 
0.728772943995648, 2.94711348173489, 3.8, 5.6, 5.3, 225.46, 1.3166764031816, 
5.37163987870506, 6.9, 3.9, 5.8, 224.68, 0.505479758443306, 2.03730134824023, 
2.8, 3, 2.8, 188.79, 1.27132281943998, 5.18309150889384, 2.4, 
6.2, 3.3, 155.89, 0.418706518938405, 1.68537437766743, 1.6, 0.8, 
1, 181.85, 0.603009515379505, 2.43394312891887, 3.4, 3.2, 3.8, 
184.46, 0.908096280087523, 3.68216367220411, 3.4, 3.2, 3.7, 195.2, 
0.941152135691392, 3.81808882463079, 3, 3.9, 3.2, 152.44, 0.740153317472902, 
2.99364537637679, 2.9, 1.4, 2, 170.13, 0.129480313106933, 0.518928030100563, 
-2.6, 1.7, -0.9, 362.83, 2.851716415795, 11.9041453782132, 12.1, 
9.8, 9.7, 261.99, 4.53674886282021, 19.4196947981818, 2.1, 4.9, 
2.1, NA, NA, NA, 3.3, 3, 3.1)), class = c("grouped_df", "tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -132L), groups = structure(list(
    setores_e_subsetores = structure(1:22, levels = c("Agropecuária", 
    "Indústria", "Indústrias extrativas", "Indústrias de transformação", 
    "Eletricidade e gás, água, esgoto, atividades de gestão de resíduos", 
    "Construção", "Serviços", "Comércio", "Transporte, armazenagem e correio", 
    "Informação e comunicação", "Atividades financeiras, de seguros e serviços relacionados", 
    "Atividades imobiliárias", "Outras atividades de serviços", 
    "Administração, saúde e educação públicas e seguridade social", 
    "Consumo das Famílias", "Consumo do Governo", "FBCF", "Exportação", 
    "Importação (-)", "Valor Adicionado (pb)", "Impostos (líq. s/ prod.)", 
    "PIB (pm)"), class = "factor"), .rows = structure(list(1:6, 
        7:12, 13:18, 19:24, 25:30, 31:36, 37:42, 43:48, 49:54, 
        55:60, 61:66, 67:72, 73:78, 79:84, 97:102, 103:108, 109:114, 
        115:120, 121:126, 85:90, 127:132, 91:96), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, -22L), .drop = TRUE, class = c("tbl_df", 
"tbl", "data.frame")))

Solution

  • No need for quosures. You can simply use a list.

    And as a suggestion. Especially when using map and walk and when dealing with a large function: Split your code in parts for easier testing and debugging!!

    Note: Even after fixing I got an error

    The following row indices do not exist in the data: 9, 10, 11.

    Hence, I dropped the cells_stub(rows = 9:11)) which caused the issue.

    library(tidyverse)
    library(gt)
    
    tab_specs <- tibble(
      filtro = list(
        c("Agropecuária", "Indústria", "Serviços", "PIB (pm)", "sub_demanda", "Valor Adicionado (pb)", "Impostos (líq. s/ prod.)"),
        c("Indústria", "sub_industria"),
        c("Serviços", "sub_servicos")
      ),
      titulo = c("**Tabela 1. Variação do PIB (%)**", "**Tabela 2. Variação do PIB na Indústria (%)**", "**Tabela 3. Variação do PIB nos Serviços (%)**"),
      especifico = list(
        list(
          style = list(
            cell_borders(sides = c("top"), color = "black", weight = px(2.5), style = "solid"),
            cell_text(weight = "bold")
          ),
          locations = list(
            cells_body(rows = 4),
            cells_stub(rows = 1:2)
          )
        ),
        list(
          style = cell_borders(sides = c("bottom"), color = "black", weight = px(2.5), style = "solid"),
          locations = list(cells_body(rows = 1), cells_stub(rows = 1))
        ),
        list(
          style = cell_borders(sides = c("bottom"), color = "black", weight = px(2.5), style = "solid"),
          locations = list(cells_body(rows = 1), cells_stub(rows = 1))
        )
      ),
      save = c("PIB", "PIB_Industria", "PIB_Serviços")
    )
    
    table_fun <- function(filtro, titulo, especifico, save) {
      data <- pib_tri %>%
        filter(
          setores_e_subsetores %in% filtro,
          variavel != "Número-índice"
        ) %>%
        pivot_wider(names_from = "variavel", values_from = "valor") %>%
        arrange(setores_e_subsetores)
    
      data %>%
        gt(rowname_col = "setores_e_subsetores", groupname_col = NA) %>%
        cols_hide(c(mes, trimestre)) %>%
        tab_header(
          title = md(titulo),
          subtitle = md(unique(.$`_data`$trimestre))
        ) %>%
        tab_source_note(source_note = md("Fonte: IBGE. Elaboração própria.")) %>%
        tab_spanner(
          label = "QoQ (SA)",
          columns = c(QoQ, `QoQ Anualizado`)
        ) %>%
        tab_style(
          style = cell_text(weight = "bold"),
          locations = cells_body(columns = 5)
        ) %>%
        tab_style(
          style = cell_text(color = "black"),
          locations = cells_body()
        ) %>%
        tab_style(
          style = cell_text(
            color = "darkgrey",
            font = google_font("Source Sans Pro")
          ),
          locations = cells_column_labels(everything())
        ) %>%
        tab_style(
          style = especifico$style,
          locations = especifico$locations
        ) %>%
        opt_table_font(font = list(google_font("Lato"), default_fonts())) %>%
        tab_options(
          heading.title.font.size = 25,
          heading.subtitle.font.size = 22,
          heading.align = "left",
          table.border.top.style = "hidden",
          heading.border.bottom.style = "hidden",
          table.font.size = 20,
          source_notes.border.bottom.style = "hidden",
          source_notes.padding = px(10),
          data_row.padding = px(10)
        ) %>%
        fmt_number(decimals = 2) %>%
        cols_align("center") %>%
        cols_width(
          stub() ~ px(300),
          everything() ~ px(130)
        ) %>%
        gtsave(paste0(save, ".png"))
    }
    
    pwalk(tab_specs, table_fun)
    

    enter image description here