Home > Net >  How to save multiple tables as images using kable and map?
How to save multiple tables as images using kable and map?

Time:09-26

I'm trying to create multiple tables from a single dataframe and save them as images. When I'm trying to save the tables using save_kable something goes wrong. This is proxy of my code:

table_list  %>%
  group_split(compound, .keep = FALSE) %>%
  setNames(unique(table_list$compound)) %>%
   map(~save_kable(file = paste0('output/final_plots/1. model performance/',
                            names(.),
                            'table_metrics.png'),
              width = 6, height = 4, 
              bs_theme = 'journal', 
              self_contained = T, 
              x = kbl(., booktabs = T, align = c('l','l', 'c')) %>%
   kable_styling() %>%
    add_header_above(c(' ' = 1,
                       ' ' = 1,
                       'Metrics' = 5))))

The idea is to create a single table per split and save it as a png. Any ideas what might be wrong?

This is my dataframe

structure(list(`Avg type` = c("hourly", "hourly", "hourly", "hourly", 
"hourly", "hourly", "hourly", "hourly", "hourly", "hourly", "hourly", 
"hourly", "hourly", "hourly", "hourly", "hourly", "hourly", "hourly", 
"hourly", "hourly", "daily", "daily", "daily", "daily", "daily", 
"daily", "daily", "daily", "daily", "daily", "daily", "daily", 
"daily", "daily", "daily", "daily", "daily", "daily", "daily", 
"daily"), Scenario = c("CCTM EFmaps", "CCTM PFT", "GC EFmaps", 
"GC EFmaps LD", "GC PFT", "CCTM EFmaps", "CCTM PFT", "GC EFmaps", 
"GC EFmaps LD", "GC PFT", "CCTM EFmaps", "CCTM PFT", "GC EFmaps", 
"GC EFmaps LD", "GC PFT", "CCTM EFmaps", "CCTM PFT", "GC EFmaps", 
"GC EFmaps LD", "GC PFT", "CCTM EFmaps", "CCTM PFT", "GC EFmaps", 
"GC EFmaps LD", "GC PFT", "CCTM EFmaps", "CCTM PFT", "GC EFmaps", 
"GC EFmaps LD", "GC PFT", "CCTM EFmaps", "CCTM PFT", "GC EFmaps", 
"GC EFmaps LD", "GC PFT", "CCTM EFmaps", "CCTM PFT", "GC EFmaps", 
"GC EFmaps LD", "GC PFT"), compound = c("ISOP", "ISOP", "ISOP", 
"ISOP", "ISOP", "MACR_MVK", "MACR_MVK", "MACR_MVK", "MACR_MVK", 
"MACR_MVK", "MTP", "MTP", "MTP", "MTP", "MTP", "O3", "O3", "O3", 
"O3", "O3", "ISOP", "ISOP", "ISOP", "ISOP", "ISOP", "MACR_MVK", 
"MACR_MVK", "MACR_MVK", "MACR_MVK", "MACR_MVK", "MTP", "MTP", 
"MTP", "MTP", "MTP", "O3", "O3", "O3", "O3", "O3"), `Pearson coeff.` = c(0.73, 
0.74, 0.76, 0.76, 0.88, 0.34, 0.43, 0.66, 0.66, 0.79, 0.46, 0.48, 
0.26, 0.19, 0.3, 0.52, 0.64, 0.64, 0.63, 0.65, 0.83, 0.83, 0.89, 
0.9, 0.94, 0.71, 0.79, 0.89, 0.89, 0.96, 0.45, 0.48, 0.31, 0.28, 
0.41, 0.14, 0.66, 0.61, 0.61, 0.63), `Mean bias` = c(4.81, 0.23, 
0.18, 0.18, -0.19, 0.45, -0.08, 0.36, 0.36, -0.03, 0.53, 0.32, 
-0.07, -0.09, -0.08, 1.63, 0.27, 5.12, 5.07, 4, 5.22, 0.25, 0.2, 
0.2, -0.2, 0.44, -0.09, 0.36, 0.36, -0.03, 0.58, 0.35, -0.07, 
-0.09, -0.08, 1.44, 0.58, 5.36, 5.32, 4.19), `Mean error` = c(4.82, 
0.33, 0.43, 0.43, 0.21, 0.54, 0.18, 0.43, 0.43, 0.15, 0.54, 0.34, 
0.1, 0.1, 0.09, 9.26, 7.14, 8.25, 8.22, 7.17, 5.22, 0.27, 0.4, 
0.4, 0.2, 0.44, 0.12, 0.39, 0.39, 0.07, 0.58, 0.35, 0.09, 0.1, 
0.08, 6, 3.63, 6.57, 6.52, 5.39), RMSE = c(0.37, 0.03, 0.05, 
0.05, 0.01, 0.04, 0.02, 0.04, 0.04, 0.01, 0.04, 0.02, 0.01, 0.01, 
0.01, 0.51, 0.37, 0.43, 0.43, 0.37, 1.37, 0.07, 0.16, 0.16, 0.04, 
0.11, 0.05, 0.12, 0.12, 0.02, 0.13, 0.08, 0.02, 0.02, 0.02, 1.32, 
0.79, 1.37, 1.36, 1.14), `Scatter Index` = c(1.1, 0.07, 0.13, 
0.13, 0.04, 0.17, 0.08, 0.17, 0.17, 0.05, 0.31, 0.18, 0.06, 0.06, 
0.06, 0.03, 0.02, 0.02, 0.02, 0.02, 3.89, 0.21, 0.44, 0.44, 0.12, 
0.46, 0.21, 0.53, 0.53, 0.08, 1.03, 0.61, 0.16, 0.17, 0.15, 0.07, 
0.04, 0.07, 0.07, 0.06)), row.names = c(NA, -40L), class = c("tbl_df", 
"tbl", "data.frame"))

CodePudding user response:

  • map does not have access to names of the dataframe so using names(.) would not work. You can use imap which by default passes data and name.

  • group_split setNames can be combined together in one step if you use split.

You can try -

library(dplyr)
library(purrr)
library(kableExtra)

table_list  %>%
  split(.$compound) %>%
  imap(~
    save_kable(file = paste0('output/final_plots/1. model performance/',.y,
                                'table_metrics.png'),
                  bs_theme = 'journal', 
                  self_contained = T, 
                  x = kbl(.x, booktabs = T, align = c('l','l', 'c')) %>%
                    kable_styling() 
                   )
    )

CodePudding user response:

We may also do this without splitting i.e. using nest_by from dplyr

library(dplyr)
library(stringr)
table_list %>%
    nest_by(compound) %>% 
    mutate(filename = file.path('output/final_plots/1. model performance', 
          str_c(compound, 'table_metrics.png')),
     new = save_kable(file = filename, bs_theme = "journal", 
      self_contained = TRUE, x = kbl(data, booktabs = TRUE,
            align = c('l','l', 'c')) %>%
            kable_styling))

-output

enter image description here

  •  Tags:  
  • r
  • Related