From 7db21d1f977fa6ded6c3b2f3a56d571dbd1ae6f2 Mon Sep 17 00:00:00 2001 From: Stefan Nygaard Hansen Date: Fri, 30 Aug 2024 10:13:49 +0200 Subject: [PATCH 1/6] Fix table widths for latex tables Add tests for setting table widths for latex tables --- R/utils_render_latex.R | 51 +++++--- tests/testthat/test-l_cols_width.R | 193 +++++++++++++++++++++++++++++ 2 files changed, 229 insertions(+), 15 deletions(-) create mode 100644 tests/testthat/test-l_cols_width.R diff --git a/R/utils_render_latex.R b/R/utils_render_latex.R index c54975226..190a754c8 100644 --- a/R/utils_render_latex.R +++ b/R/utils_render_latex.R @@ -148,11 +148,29 @@ create_table_start_l <- function(data, colwidth_df) { # Get vector representation of stub layout stub_layout <- get_stub_layout(data = data) - # Get default alignments for body columns - col_alignment <- dt_boxhead_get_vars_align_default(data = data) - - if (length(stub_layout) > 0) { - col_alignment <- c(rep("left", length(stub_layout)), col_alignment) + # Extract only visible columns of `colwidth_df`. + row_group_as_column <- + dt_options_get_value( + data = data, + option = "row_group_as_column" + ) + + types <- c("default", "stub", if (row_group_as_column) "row_group" else NULL) + colwidth_df_visible <- colwidth_df[colwidth_df$type %in% types, ] + + # Ensure that the `colwidth_df_visible` df rows are sorted such that the + # `"row_group"` row is first (only if it's located in the stub), then `"stub"`, + # and then everything else + if ("stub" %in% colwidth_df_visible[["type"]]) { + stub_idx <- which(colwidth_df_visible$type == "stub") + othr_idx <- base::setdiff(seq_len(nrow(colwidth_df_visible)), stub_idx) + colwidth_df_visible <- dplyr::slice(colwidth_df_visible, stub_idx, othr_idx) + } + + if ("row_group" %in% colwidth_df_visible[["type"]] && row_group_as_column) { + row_group_idx <- which(colwidth_df_visible$type == "row_group") + othr_idx <- base::setdiff(seq_len(nrow(colwidth_df_visible)), row_group_idx) + colwidth_df_visible <- dplyr::slice(colwidth_df_visible, row_group_idx, othr_idx) } # Determine if there are any footnotes or source notes; if any, @@ -176,19 +194,19 @@ create_table_start_l <- function(data, colwidth_df) { # - `>{\centering\arraybackslash}` <- center alignment # the `\arraybackslash` command is used to restore the behavior of the # `\\` command in the table (all of this uses the CTAN `array` package) - if (any(colwidth_df$unspec < 1L)) { + if (any(colwidth_df_visible$unspec < 1L)) { col_defs <- NULL - for (i in seq_along(col_alignment)) { - - if (colwidth_df$unspec[i] == 1L) { - col_defs_i <- substr(col_alignment[i], 1, 1) + for (i in seq_len(nrow(colwidth_df_visible))) { + + if (colwidth_df_visible$unspec[i] == 1L) { + col_defs_i <- substr(colwidth_df_visible$column_align[i], 1, 1) } else { align <- switch( - col_alignment[i], + colwidth_df_visible$column_align[i], left = ">{\\raggedright\\arraybackslash}", right = ">{\\raggedleft\\arraybackslash}", center = ">{\\centering\\arraybackslash}", @@ -199,7 +217,7 @@ create_table_start_l <- function(data, colwidth_df) { paste0( align, "p{", - create_singlecolumn_width_text_l(pt = colwidth_df$pt[i], lw = colwidth_df$lw[i]), + create_singlecolumn_width_text_l(pt = colwidth_df_visible$pt[i], lw = colwidth_df_visible$lw[i]), "}" ) @@ -209,8 +227,8 @@ create_table_start_l <- function(data, colwidth_df) { } } else { - - col_defs <- substr(col_alignment, 1, 1) + + col_defs <- substr(colwidth_df_visible$column_align, 1, 1) } # Add borders to the right of any columns in the stub @@ -1685,8 +1703,11 @@ create_colwidth_df_l <- function(data) { type = boxhead$type, unspec = rep.int(0L, n), lw = rep.int(0L, n), - pt = rep.int(0L, n) + pt = rep.int(0L, n), + column_align = boxhead$column_align ) + + width_df$align[width_df$type %in% c("stub", "row_group")] <- "left" for (i in 1:n) { raw <- unlist(boxhead$column_width[i])[1L] diff --git a/tests/testthat/test-l_cols_width.R b/tests/testthat/test-l_cols_width.R new file mode 100644 index 000000000..6146cfc5b --- /dev/null +++ b/tests/testthat/test-l_cols_width.R @@ -0,0 +1,193 @@ +test_that("cols_width() works correctly", { + + # Create a `tbl_latex` object with `gt()`: + # The `mpg` and `cyl` columns with one width, and the `cyl` and `hp` + # columns with another width. + + tbl <- mtcars_short |> + gt() |> + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear", "carb")) |> + cols_width( + c("mpg", "disp") ~ px(150), + c("cyl", "hp") ~ px(100) + ) + + tbl_latex_tabul <- tbl |> + as_latex() |> + as.character() + + tbl_latex_lt <- tbl |> + tab_options(latex.use_longtable = TRUE) |> + as_latex() |> + as.character() + + # Expect a characteristic pattern depending whether longtable or tabular is used. + expect_length(tbl_latex_lt, 1) + expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 75.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 75.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + + expect_length(tbl_latex_tabul, 1) + expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 75.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 75.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + + # Create a `tbl_latex` object with `gt()`: + # The `mpg` and `cyl` columns are merged having one width, + # and the `cyl` and `hp` columns are merged having another width. + + tbl <- mtcars_short |> + gt() |> + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear", "carb")) |> + cols_merge( + columns = c("mpg", "cyl"), + pattern = "{1}-{2}" + ) |> + cols_merge( + columns = c("disp", "hp"), + pattern = "{1}-{2}" + ) |> + cols_width( + "mpg" ~ px(150), + "disp" ~ px(200) + ) + + tbl_latex_tabul <- tbl |> + as_latex() |> + as.character() + + tbl_latex_lt <- tbl |> + tab_options(latex.use_longtable = TRUE) |> + as_latex() |> + as.character() + + # Expect a characteristic pattern depending whether longtable or tabular is used. + expect_length(tbl_latex_lt, 1) + expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + + expect_length(tbl_latex_tabul, 1) + expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + + # Create a `tbl_latex` object with `gt()`: + # `carb` is used a stub with a specific width. + # The `mpg` and `cyl` columns are merged having one width, + # and the `cyl` and `hp` columns are merged having another width. + + tbl <- mtcars_short |> + gt(rowname_col = "carb") |> + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear")) |> + tab_stubhead(label = "carb") |> + cols_merge( + columns = c("mpg", "cyl"), + pattern = "{1}-{2}" + ) |> + cols_merge( + columns = c("disp", "hp"), + pattern = "{1}-{2}" + ) |> + cols_width( + "mpg" ~ px(150), + "disp" ~ px(200), + "carb" ~ px(75) + ) + + tbl_latex_tabul <- tbl |> + as_latex() |> + as.character() + + tbl_latex_lt <- tbl |> + tab_options(latex.use_longtable = TRUE) |> + as_latex() |> + as.character() + + # Expect a characteristic pattern depending whether longtable or tabular is used. + expect_length(tbl_latex_lt, 1) + expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + + expect_length(tbl_latex_tabul, 1) + expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + + # Create a `tbl_latex` object with `gt()`: + # `carb` is used a stub with a specific width, and `carb_group` is used as row_groups. + # The `mpg` and `cyl` columns are merged having one width, + # and the `cyl` and `hp` columns are merged having another width. + # We set the width of the row_groups here to check that the table isn't + # affected since `row_group_as_column` is FALSE. + + tbl <- mtcars_short |> + dplyr::mutate(carb_grp = ifelse(carb <= 2, "<=2", ">2")) |> + gt(rowname_col = "carb", groupname_col = "carb_grp") |> + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear")) |> + tab_stubhead(label = "carb") |> + cols_merge( + columns = c("mpg", "cyl"), + pattern = "{1}-{2}" + ) |> + cols_merge( + columns = c("disp", "hp"), + pattern = "{1}-{2}" + ) |> + cols_width( + "mpg" ~ px(150), + "disp" ~ px(200), + "carb" ~ px(75), + "carb_grp"~ px(1000) + ) + + tbl_latex_tabul <- tbl |> + as_latex() |> + as.character() + + tbl_latex_lt <- tbl |> + tab_options(latex.use_longtable = TRUE) |> + as_latex() |> + as.character() + + # Expect a characteristic pattern depending whether longtable or tabular is used. + expect_length(tbl_latex_lt, 1) + expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + + expect_length(tbl_latex_tabul, 1) + expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + + # Create a `tbl_latex` object with `gt()`: + # `carb` is used a stub with a specific width, and `carb_group` is used as row_groups + # getting its own column with its own width. + # The `mpg` and `cyl` columns are merged having one width, + # and the `cyl` and `hp` columns are merged having another width. + + tbl <- mtcars_short |> + dplyr::mutate(carb_grp = ifelse(carb <= 2, "<=2", ">2")) |> + gt(rowname_col = "carb", + groupname_col = "carb_grp", + row_group_as_column = TRUE + ) |> + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear")) |> + tab_stubhead(label = "carb") |> + cols_merge( + columns = c("mpg", "cyl"), + pattern = "{1}-{2}" + ) |> + cols_merge( + columns = c("disp", "hp"), + pattern = "{1}-{2}" + ) |> + cols_width( + "mpg" ~ px(150), + "disp" ~ px(200), + "carb" ~ px(75), + "carb_grp"~ px(50) + ) + + tbl_latex_tabul <- tbl |> + as_latex() |> + as.character() + + tbl_latex_lt <- tbl |> + tab_options(latex.use_longtable = TRUE) |> + as_latex() |> + as.character() + + # Expect a characteristic pattern depending whether longtable or tabular is used. + expect_length(tbl_latex_lt, 1) + expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 37.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + + expect_length(tbl_latex_tabul, 1) + expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 37.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") +}) \ No newline at end of file From 95a3314012d4f5f19e9db69497916912b7aff832 Mon Sep 17 00:00:00 2001 From: Stefan Nygaard Hansen Date: Fri, 30 Aug 2024 10:24:46 +0200 Subject: [PATCH 2/6] Add NEWS item --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 72f387f51..0936a9a6f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -23,6 +23,8 @@ ## Bug fixes +* Fixed an issue where column widths weren't set properly using `col_widths()` for LaTeX output. (#1837) + * Improved error messages for the `text_transform()` function if `locations` couldn't be resolved. (@olivroy, #1774) * `tab_row_group()` gives a more precise error message when `rows` can't be resolved correctly (#1535). (@olivroy, #1770) From c08b35fee577badeb9e9c3d3d58af2dcc91eab50 Mon Sep 17 00:00:00 2001 From: Stefan Nygaard Hansen Date: Fri, 30 Aug 2024 14:59:05 +0200 Subject: [PATCH 3/6] Use magrittr pipe instead of native pipe --- tests/testthat/test-l_cols_width.R | 106 ++++++++++++++--------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/tests/testthat/test-l_cols_width.R b/tests/testthat/test-l_cols_width.R index 6146cfc5b..8910c87fa 100644 --- a/tests/testthat/test-l_cols_width.R +++ b/tests/testthat/test-l_cols_width.R @@ -4,21 +4,21 @@ test_that("cols_width() works correctly", { # The `mpg` and `cyl` columns with one width, and the `cyl` and `hp` # columns with another width. - tbl <- mtcars_short |> - gt() |> - cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear", "carb")) |> + tbl <- mtcars_short %>% + gt() %>% + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear", "carb")) %>% cols_width( c("mpg", "disp") ~ px(150), c("cyl", "hp") ~ px(100) ) - tbl_latex_tabul <- tbl |> - as_latex() |> + tbl_latex_tabul <- tbl %>% + as_latex() %>% as.character() - tbl_latex_lt <- tbl |> - tab_options(latex.use_longtable = TRUE) |> - as_latex() |> + tbl_latex_lt <- tbl %>% + tab_options(latex.use_longtable = TRUE) %>% + as_latex() %>% as.character() # Expect a characteristic pattern depending whether longtable or tabular is used. @@ -32,29 +32,29 @@ test_that("cols_width() works correctly", { # The `mpg` and `cyl` columns are merged having one width, # and the `cyl` and `hp` columns are merged having another width. - tbl <- mtcars_short |> - gt() |> - cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear", "carb")) |> + tbl <- mtcars_short %>% + gt() %>% + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear", "carb")) %>% cols_merge( columns = c("mpg", "cyl"), pattern = "{1}-{2}" - ) |> + ) %>% cols_merge( columns = c("disp", "hp"), pattern = "{1}-{2}" - ) |> + ) %>% cols_width( "mpg" ~ px(150), "disp" ~ px(200) ) - tbl_latex_tabul <- tbl |> - as_latex() |> + tbl_latex_tabul <- tbl %>% + as_latex() %>% as.character() - tbl_latex_lt <- tbl |> - tab_options(latex.use_longtable = TRUE) |> - as_latex() |> + tbl_latex_lt <- tbl %>% + tab_options(latex.use_longtable = TRUE) %>% + as_latex() %>% as.character() # Expect a characteristic pattern depending whether longtable or tabular is used. @@ -69,31 +69,31 @@ test_that("cols_width() works correctly", { # The `mpg` and `cyl` columns are merged having one width, # and the `cyl` and `hp` columns are merged having another width. - tbl <- mtcars_short |> - gt(rowname_col = "carb") |> - cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear")) |> - tab_stubhead(label = "carb") |> + tbl <- mtcars_short %>% + gt(rowname_col = "carb") %>% + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear")) %>% + tab_stubhead(label = "carb") %>% cols_merge( columns = c("mpg", "cyl"), pattern = "{1}-{2}" - ) |> + ) %>% cols_merge( columns = c("disp", "hp"), pattern = "{1}-{2}" - ) |> + ) %>% cols_width( "mpg" ~ px(150), "disp" ~ px(200), "carb" ~ px(75) ) - tbl_latex_tabul <- tbl |> - as_latex() |> + tbl_latex_tabul <- tbl %>% + as_latex() %>% as.character() - tbl_latex_lt <- tbl |> - tab_options(latex.use_longtable = TRUE) |> - as_latex() |> + tbl_latex_lt <- tbl %>% + tab_options(latex.use_longtable = TRUE) %>% + as_latex() %>% as.character() # Expect a characteristic pattern depending whether longtable or tabular is used. @@ -110,19 +110,19 @@ test_that("cols_width() works correctly", { # We set the width of the row_groups here to check that the table isn't # affected since `row_group_as_column` is FALSE. - tbl <- mtcars_short |> - dplyr::mutate(carb_grp = ifelse(carb <= 2, "<=2", ">2")) |> - gt(rowname_col = "carb", groupname_col = "carb_grp") |> - cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear")) |> - tab_stubhead(label = "carb") |> + tbl <- mtcars_short %>% + dplyr::mutate(carb_grp = ifelse(carb <= 2, "<=2", ">2")) %>% + gt(rowname_col = "carb", groupname_col = "carb_grp") %>% + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear")) %>% + tab_stubhead(label = "carb") %>% cols_merge( columns = c("mpg", "cyl"), pattern = "{1}-{2}" - ) |> + ) %>% cols_merge( columns = c("disp", "hp"), pattern = "{1}-{2}" - ) |> + ) %>% cols_width( "mpg" ~ px(150), "disp" ~ px(200), @@ -130,13 +130,13 @@ test_that("cols_width() works correctly", { "carb_grp"~ px(1000) ) - tbl_latex_tabul <- tbl |> - as_latex() |> + tbl_latex_tabul <- tbl %>% + as_latex() %>% as.character() - tbl_latex_lt <- tbl |> - tab_options(latex.use_longtable = TRUE) |> - as_latex() |> + tbl_latex_lt <- tbl %>% + tab_options(latex.use_longtable = TRUE) %>% + as_latex() %>% as.character() # Expect a characteristic pattern depending whether longtable or tabular is used. @@ -152,22 +152,22 @@ test_that("cols_width() works correctly", { # The `mpg` and `cyl` columns are merged having one width, # and the `cyl` and `hp` columns are merged having another width. - tbl <- mtcars_short |> - dplyr::mutate(carb_grp = ifelse(carb <= 2, "<=2", ">2")) |> + tbl <- mtcars_short %>% + dplyr::mutate(carb_grp = ifelse(carb <= 2, "<=2", ">2")) %>% gt(rowname_col = "carb", groupname_col = "carb_grp", row_group_as_column = TRUE - ) |> - cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear")) |> - tab_stubhead(label = "carb") |> + ) %>% + cols_hide(c("drat", "wt", "qsec", "vs", "am", "gear")) %>% + tab_stubhead(label = "carb") %>% cols_merge( columns = c("mpg", "cyl"), pattern = "{1}-{2}" - ) |> + ) %>% cols_merge( columns = c("disp", "hp"), pattern = "{1}-{2}" - ) |> + ) %>% cols_width( "mpg" ~ px(150), "disp" ~ px(200), @@ -175,13 +175,13 @@ test_that("cols_width() works correctly", { "carb_grp"~ px(50) ) - tbl_latex_tabul <- tbl |> - as_latex() |> + tbl_latex_tabul <- tbl %>% + as_latex() %>% as.character() - tbl_latex_lt <- tbl |> - tab_options(latex.use_longtable = TRUE) |> - as_latex() |> + tbl_latex_lt <- tbl %>% + tab_options(latex.use_longtable = TRUE) %>% + as_latex() %>% as.character() # Expect a characteristic pattern depending whether longtable or tabular is used. From 120d1a22dbb5f7cd105a71213480fb08bb6a5526 Mon Sep 17 00:00:00 2001 From: Stefan Nygaard Hansen Date: Fri, 30 Aug 2024 18:23:43 +0200 Subject: [PATCH 4/6] Fix incorrect column reference --- R/utils_render_latex.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/utils_render_latex.R b/R/utils_render_latex.R index 190a754c8..6007a51c9 100644 --- a/R/utils_render_latex.R +++ b/R/utils_render_latex.R @@ -1707,7 +1707,7 @@ create_colwidth_df_l <- function(data) { column_align = boxhead$column_align ) - width_df$align[width_df$type %in% c("stub", "row_group")] <- "left" + width_df$column_align[width_df$type %in% c("stub", "row_group")] <- "left" for (i in 1:n) { raw <- unlist(boxhead$column_width[i])[1L] From 2d6441ad6c08da4ca7fa809c0e1d40565920f7a9 Mon Sep 17 00:00:00 2001 From: Stefan Nygaard Hansen Date: Fri, 30 Aug 2024 19:44:58 +0200 Subject: [PATCH 5/6] Handle stub columns differently --- R/utils_render_latex.R | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/R/utils_render_latex.R b/R/utils_render_latex.R index 6007a51c9..7b579902e 100644 --- a/R/utils_render_latex.R +++ b/R/utils_render_latex.R @@ -148,14 +148,15 @@ create_table_start_l <- function(data, colwidth_df) { # Get vector representation of stub layout stub_layout <- get_stub_layout(data = data) - # Extract only visible columns of `colwidth_df`. - row_group_as_column <- - dt_options_get_value( - data = data, - option = "row_group_as_column" - ) + # Extract only visible columns of `colwidth_df` based on stub_layout. + types <- c("default") + if ("rowname" %in% stub_layout) { + types <- c(types, "stub") + } + if ("group_label" %in% stub_layout) { + types <- c(types, "row_group") + } - types <- c("default", "stub", if (row_group_as_column) "row_group" else NULL) colwidth_df_visible <- colwidth_df[colwidth_df$type %in% types, ] # Ensure that the `colwidth_df_visible` df rows are sorted such that the @@ -167,7 +168,7 @@ create_table_start_l <- function(data, colwidth_df) { colwidth_df_visible <- dplyr::slice(colwidth_df_visible, stub_idx, othr_idx) } - if ("row_group" %in% colwidth_df_visible[["type"]] && row_group_as_column) { + if ("row_group" %in% colwidth_df_visible[["type"]]) { row_group_idx <- which(colwidth_df_visible$type == "row_group") othr_idx <- base::setdiff(seq_len(nrow(colwidth_df_visible)), row_group_idx) colwidth_df_visible <- dplyr::slice(colwidth_df_visible, row_group_idx, othr_idx) From 53504b82cfc0a48b1bee93bf2d9df30438402dc2 Mon Sep 17 00:00:00 2001 From: Stefan Nygaard Hansen Date: Fri, 30 Aug 2024 21:57:34 +0200 Subject: [PATCH 6/6] Fix alignment mistake in unit test for cols_width --- tests/testthat/test-l_cols_width.R | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/testthat/test-l_cols_width.R b/tests/testthat/test-l_cols_width.R index 8910c87fa..daa2e61f5 100644 --- a/tests/testthat/test-l_cols_width.R +++ b/tests/testthat/test-l_cols_width.R @@ -98,10 +98,10 @@ test_that("cols_width() works correctly", { # Expect a characteristic pattern depending whether longtable or tabular is used. expect_length(tbl_latex_lt, 1) - expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") - + expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + expect_length(tbl_latex_tabul, 1) - expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") # Create a `tbl_latex` object with `gt()`: # `carb` is used a stub with a specific width, and `carb_group` is used as row_groups. @@ -141,10 +141,10 @@ test_that("cols_width() works correctly", { # Expect a characteristic pattern depending whether longtable or tabular is used. expect_length(tbl_latex_lt, 1) - expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") expect_length(tbl_latex_tabul, 1) - expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") # Create a `tbl_latex` object with `gt()`: # `carb` is used a stub with a specific width, and `carb_group` is used as row_groups @@ -186,8 +186,8 @@ test_that("cols_width() works correctly", { # Expect a characteristic pattern depending whether longtable or tabular is used. expect_length(tbl_latex_lt, 1) - expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 37.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + expect_match(tbl_latex_lt, "\\\\begin\\{longtable\\}\\{>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 37.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") expect_length(tbl_latex_tabul, 1) - expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 37.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") + expect_match(tbl_latex_tabul, "\\\\begin\\{tabular\\*\\}\\{\\\\linewidth\\}\\{@\\{\\\\extracolsep\\{\\\\fill\\}\\}>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 37.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedright\\\\arraybackslash\\}p\\{\\\\dimexpr 56.25pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}|>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 112.50pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}>\\{\\\\raggedleft\\\\arraybackslash\\}p\\{\\\\dimexpr 150.00pt -2\\\\tabcolsep-1.5\\\\arrayrulewidth\\}\\}") }) \ No newline at end of file