skip_on_cran() my_tbl_summary <- trial |> select(trt, age, death) |> tbl_summary() my_tbl_regression <- lm(marker ~ age, trial) |> tbl_regression() my_spanning_tbl <- trial |> tbl_summary(by = grade, include = age) |> modify_spanning_header(c(stat_1, stat_3) ~ "**Testing**") gt_tbl_summary <- my_tbl_summary |> as_gt() gt_tbl_regression <- my_tbl_regression |> as_gt() gt_spanning_tbl <- my_spanning_tbl |> as_gt() test_that("as_gt works with standard use", { # return_calls argument does not produce warnings expect_silent(my_tbl_summary |> as_gt(return_calls = TRUE)) # include argument does not produce warnings expect_silent(my_tbl_summary |> as_gt(include = gt)) # correct elements are returned expect_equal( names(gt_tbl_summary), c("_data", "_boxhead", "_stub_df", "_row_groups", "_heading", "_spanners", "_stubhead", "_footnotes", "_source_notes", "_formats", "_substitutions", "_styles", "_summary", "_options", "_transforms", "_locale", "_has_built") ) }) test_that("as_gt passes table body correctly", { # tbl_summary expect_equal( my_tbl_summary$table_body, gt_tbl_summary$`_data` ) # tbl_cross my_tbl_cross <- tbl_cross(trial, trt, grade) expect_silent(gt_tbl_cross <- my_tbl_cross |> as_gt()) expect_equal( my_tbl_cross$table_body |> as_tibble(), gt_tbl_cross$`_data` ) # tbl_regression expect_equal( my_tbl_regression$table_body, gt_tbl_regression$`_data`, ignore_attr = "class" ) # tbl_uvregression my_tbl_uvregression <- trial |> tbl_uvregression(method = lm, y = age) expect_silent(gt_tbl_uvregression <- my_tbl_uvregression |> as_gt()) expect_equal( my_tbl_uvregression$table_body, gt_tbl_uvregression$`_data`, ignore_attr = "class" ) # spanning_tbl expect_equal( my_spanning_tbl$table_body, gt_spanning_tbl$`_data` ) }) test_that("as_gt works with bold/italics", { tbl <- my_tbl_summary |> bold_labels() |> italicize_levels() gt_tbl <- tbl |> as_gt() gt_styles <- gt_tbl$`_styles` |> dplyr::arrange(rownum) |> dplyr::pull(styles) |> unlist(use.names = FALSE) # labels correctly bolded expect_equal( eval_tidy(tbl$table_styling$text_format$rows[[1]], data = tbl$table_body), gt_styles == "bold" ) # labels correctly italicized expect_equal( eval_tidy(tbl$table_styling$text_format$rows[[2]], data = tbl$table_body), gt_styles == "italic" ) }) test_that("as_gt passes table header labels correctly", { # tbl_summary expect_equal( my_tbl_summary$table_styling$header$column, gt_tbl_summary$`_boxhead`$var ) expect_equal( my_tbl_summary$table_styling$header$label, gt_tbl_summary$`_boxhead`$column_label |> unlist() ) # spanning_tbl expect_equal( my_spanning_tbl$table_styling$header$column, gt_spanning_tbl$`_boxhead`$var ) expect_equal( my_spanning_tbl$table_styling$header$label, gt_spanning_tbl$`_boxhead`$column_label |> unlist() ) # spanning_tbl - spanning header expect_equal( my_spanning_tbl$table_styling$header |> dplyr::filter(!is.na(spanning_header)) |> dplyr::pull(column), gt_spanning_tbl$`_spanners`$vars[[1]] ) }) test_that("as_gt passes table column visibility correctly", { expect_equal( my_tbl_regression$table_styling$header |> dplyr::filter(!hide) |> dplyr::pull(column), gt_tbl_regression$`_boxhead` |> dplyr::filter(type != "hidden") |> dplyr::pull(var) ) # customize visibility tbl <- my_tbl_regression |> modify_table_styling(columns = "estimate", hide = TRUE) |> modify_table_styling(columns = "N_obs", hide = FALSE) gt_tbl <- tbl |> as_gt() expect_equal( tbl$table_styling$header |> dplyr::filter(!hide) |> dplyr::pull(column), gt_tbl$`_boxhead` |> dplyr::filter(type != "hidden") |> dplyr::pull(var) ) }) test_that("as_gt passes table column alignment correctly", { expect_equal( my_tbl_regression$table_styling$header |> dplyr::filter(!hide) |> dplyr::pull(align), gt_tbl_regression$`_boxhead` |> dplyr::filter(type != "hidden") |> dplyr::pull(column_align) ) # customize alignment tbl <- my_tbl_regression |> modify_table_styling(columns = "estimate", align = "right") gt_tbl <- tbl |> as_gt() expect_equal( tbl$table_styling$header |> dplyr::filter(!hide) |> dplyr::pull(align), gt_tbl$`_boxhead` |> dplyr::filter(type != "hidden") |> dplyr::pull(column_align) ) }) test_that("as_gt passes table text interpreters correctly", { # header expect_equal( lapply( my_spanning_tbl$table_styling$header$interpret_label, \(x) do.call(eval(parse(text = x)), list("")) |> class() ), lapply(gt_spanning_tbl$`_boxhead`$column_label, class) ) # spanning header expect_equal( sapply( my_spanning_tbl$table_styling$header |> dplyr::filter(!is.na(spanning_header)) |> dplyr::pull(interpret_spanning_header), \(x) do.call(eval(parse(text = x)), list("")) |> class() ), gt_spanning_tbl$`_spanners`$spanner_label[[1]] |> class() |> rep(length(gt_spanning_tbl$`_spanners`$vars[[1]])), ignore_attr = "names" ) # customize interpreter tbl <- my_spanning_tbl |> modify_table_styling(columns = "stat_1", label = "Stat I", spanning_header = "MyTest", text_interpret = "html") gt_tbl <- tbl |> as_gt() # header expect_equal( lapply( tbl$table_styling$header$interpret_label, \(x) do.call(eval(parse(text = x)), list("")) |> class() ), lapply(gt_tbl$`_boxhead`$column_label, class) ) # spanning header expect_true(attr(gt_tbl$`_spanners`$spanner_label[[1]], "html")) }) test_that("as_gt passes table footnotes & footnote abbreviations correctly", { tbl_fn <- my_tbl_summary |> modify_table_styling(columns = label, footnote = "test footnote", rows = variable == "age") gt_tbl_fn <- tbl_fn |> as_gt() # footnote expect_equal( tbl_fn$table_styling$footnote$column, gt_tbl_fn$`_footnotes`$colname |> unique() ) expect_equal( tbl_fn$table_styling$footnote$footnote, gt_tbl_fn$`_footnotes`$footnotes |> unlist() |> unique() ) tbl_fa <- tbl_fn |> modify_footnote(stat_0 = "N = number of observations", abbreviation = TRUE) gt_tbl_fa <- tbl_fa |> as_gt() # footnote_abbrev expect_equal( gt_tbl_fa$`_footnotes` |> dplyr::distinct(pick(!any_of("rownum"))) |> dplyr::arrange(locnum) |> dplyr::pull(colname), c("stat_0", "stat_0", "label") ) expect_equal( gt_tbl_fa$`_footnotes` |> dplyr::distinct(pick(!any_of("rownum"))) |> dplyr::arrange(locnum) |> dplyr::pull(footnotes) |> unlist(), c("n (%); Median (Q1, Q3)", "N = number of observations", "test footnote") ) # customized footnotes tbl <- my_tbl_summary |> modify_footnote( all_stat_cols() ~ "replace old footnote", label = "another new footnote" ) gt_tbl <- tbl |> as_gt() expect_equal( gt_tbl$`_footnotes`$colname, c("stat_0", "label") ) expect_equal( gt_tbl$`_footnotes`$footnotes |> unlist(), c("replace old footnote", "another new footnote") ) }) test_that("as_gt passes table indentation correctly", { expect_equal( my_tbl_summary$table_styling$indent$n_spaces[2], gt_tbl_summary$`_transforms`[[1]]$fn("") |> nchar() ) # indentation removed tbl <- my_tbl_summary |> modify_column_indent(columns = label, indent = 0) gt_tbl <- tbl |> as_gt() expect_equal( gt_tbl$`_transforms` |> length(), 0 ) }) test_that("as_gt passes appended glance statistics correctly", { tbl <- my_tbl_regression |> add_glance_source_note(c("r.squared", "BIC")) |> add_glance_table(c("r.squared", "BIC")) gt_tbl <- tbl |> as_gt() loc_hline <- tbl$table_body |> rownames_to_column() |> dplyr::filter(!!tbl$table_styling$horizontal_line_above) |> dplyr::pull(rowname) |> as.numeric() expect_equal( tbl$table_body |> dplyr::select(-conf.low), gt_tbl$`_data` |> dplyr::select(-conf.low), ignore_attr = "class" ) expect_equal( tbl$table_styling$source_note, gt_tbl$`_source_notes`[[1]], ignore_attr = "class" ) expect_equal( loc_hline, gt_tbl$`_styles`$rownum |> unique() ) }) test_that("as_gt passes captions correctly", { tbl <- my_tbl_regression |> modify_caption("My table caption") gt_tbl <- tbl |> as_gt() expect_equal( tbl$table_styling$caption, (gt_tbl$`_options` |> dplyr::filter(parameter == "table_caption"))$value[[1]], ignore_attr = "class" ) }) test_that("as_gt passes missing symbols correctly", { tbl <- my_tbl_summary |> modify_table_body(~ .x |> mutate(stat_0 = NA_character_)) gt_tbl <- tbl |> as_gt() # no substitution for missing values expect_equal( length(gt_tbl$`_substitutions`), 1 ) # specify missing symbol tbl <- tbl |> modify_table_styling(stat_0, rows = !is.na(label), missing_symbol = "n / a") gt_tbl <- tbl |> as_gt() # correct substitution for missing values expect_equal( tbl |> as_tibble(col_labels = FALSE, fmt_missing = TRUE) |> dplyr::pull(stat_0), gt_tbl$`_substitutions`[[2]]$func$default(gt_tbl$`_data`$stat_0) ) }) test_that("as_gt applies formatting functions correctly", { tbl <- glm(response ~ age + grade, trial, family = binomial(link = "logit")) |> tbl_regression(exponentiate = TRUE) |> modify_fmt_fun( p.value ~ function(x) style_pvalue(x, digits = 3), rows = variable == "grade" ) |> modify_fmt_fun( estimate ~ function(x) style_ratio(x, digits = 4, decimal.mark = ",") ) gt_tbl <- tbl |> as_gt() # formatted cells expect_equal( gt_tbl$`_formats`[[12]]$func$default(gt_tbl$`_data`$p.value), c("0.096", NA, NA, "0.688", "0.972") ) # formatted column expect_equal( gt_tbl$`_formats`[[14]]$func$default(gt_tbl$`_data`$estimate), c("1,0191", NA, NA, "0,8535", "1,0136") ) tbl2 <- tbl_uvregression( trial |> dplyr::select(response, age, grade), method = glm, y = response, method.args = list(family = binomial), exponentiate = TRUE ) |> modify_fmt_fun( stat_n ~ function(x) style_number(x, digits = 2), rows = variable == "age" ) |> modify_fmt_fun( stat_n ~ label_style_number(digits = 4), rows = variable == "grade" ) |> modify_fmt_fun( c(conf.low, conf.high) ~ label_style_sigfig(digits = 3) ) gt_tbl2 <- tbl2 |> as_gt() # formatted cell expect_equal( gt_tbl2$`_formats`[[22]]$func$default(gt_tbl2$`_data`$stat_n), c("183.0000", "193.0000", NA, NA, NA) ) # formatted column expect_equal( gt_tbl2$`_formats`[[23]]$func$default(gt_tbl2$`_data`$conf.low), c("0.997", NA, NA, "0.446", "0.524") ) expect_equal( gt_tbl2$`_formats`[[24]]$func$default(gt_tbl2$`_data`$conf.high), c("1.04", NA, NA, "2.00", "2.29") ) }) test_that("as_gt passes column merging correctly", { tbl <- lm(marker ~ age + grade, trial) |> tbl_regression() |> modify_column_merge( pattern = "{estimate} (pval {p.value})", rows = !is.na(estimate) & estimate < 0 ) gt_tbl <- tbl |> as_gt() # conf.low (default column merging) expect_equal( eval_tidy(tbl$table_styling$cols_merge$rows[[1]], data = tbl$table_body) |> which(), gt_tbl$`_col_merge`[[1]]$rows ) expect_equal( gt_tbl$`_col_merge`[[1]]$vars, c("conf.low", "conf.high") ) expect_equal( gt_tbl$`_col_merge`[[1]]$pattern, c("{1}, {2}") ) # estimate (added custom column merging) expect_equal( eval_tidy(tbl$table_styling$cols_merge$rows[[2]], data = tbl$table_body) |> which(), gt_tbl$`_col_merge`[[2]]$rows ) expect_equal( gt_tbl$`_col_merge`[[2]]$vars, c("estimate", "p.value") ) expect_equal( gt_tbl$`_col_merge`[[2]]$pattern, c("{1} (pval {2})") ) expect_equal( as.data.frame(gt_tbl)$estimate, c("0.00 (pval >0.9)", "
", "—", "-0.38 (pval 0.015)", "-0.12 (pval 0.5)") ) # modify column merging pattern tbl <- tbl |> modify_table_styling( columns = estimate, rows = !is.na(estimate) & estimate < 0, cols_merge_pattern = "{estimate} (p is {p.value})" ) gt_tbl <- tbl |> as_gt() expect_equal( gt_tbl$`_col_merge`[[2]]$pattern, c("{1} (p is {2})") ) expect_equal( as.data.frame(gt_tbl)$estimate, c("0.00 (p is >0.9)", "
", "—", "-0.38 (p is 0.015)", "-0.12 (p is 0.5)") ) # remove column merging tbl <- tbl |> modify_table_styling( columns = estimate, cols_merge_pattern = NA ) gt_tbl <- tbl |> as_gt() expect_equal(length(gt_tbl$`_col_merge`), 1) expect_equal( as.data.frame(gt_tbl)$estimate, c("0.00", "
", "—", "-0.38", "-0.12") ) })