Open snhansen opened 1 month ago
Just want to add that cols_width
is respected in pdf (but not html) output in the above example if "low" is replaced with "high" like this:
cols_width(
date ~ px(100),
c("open", "high") ~ px(200)
)
So it seems that the label is misattributed in latex. Maybe this can help with debugging.
I've had a related issue with latex when creating tables using gtsummary and converting to gt using as_gt()
. Couldn't modify cols_width
until I realised after using tab_info()
that labels did not match column names in the table. Specifying column width eventually worked after trial and error with labels under tab_info()
.
Good catch. I looked a bit more into it, and from what I can see the issue is with the create_table_start_l()
function in utils_render_latex.R
.
Indeed if we call the example table for ex_table
, then we get the following
data <- gt:::build_data(data = ex_table, context = "latex")
colwidth_df <- gt:::create_colwidth_df_l(data = data)
colwidth_df
#> type unspec lw pt tbl_width
#> 1 default 0 0 75 NA
#> 2 default 0 0 150 NA
#> 3 hidden 1 0 0 NA
#> 4 default 0 0 150 NA
#> 5 hidden 1 0 0 NA
so it calculates the widths correctly for the correct columns, but this is translated into LaTeX code by create_table_start_l()
incorrectly, i.e. it is missing a column specification.
gt:::create_table_start_l(data = data, colwidth_df = colwidth_df)
#> [1] "\\begin{longtable}{>{\\raggedleft\\arraybackslash}p{\\dimexpr 75.00pt -2\\tabcolsep-1.5\\arrayrulewidth}>{\\raggedleft\\arraybackslash}p{\\dimexpr 150.00pt -2\\tabcolsep-1.5\\arrayrulewidth}r}\n"
Did a bit more investigating and it's this part of the code that's not working properly (line 179-214):
if (any(colwidth_df$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)
} else {
align <-
switch(
col_alignment[i],
left = ">{\\raggedright\\arraybackslash}",
right = ">{\\raggedleft\\arraybackslash}",
center = ">{\\centering\\arraybackslash}",
">{\\raggedright\\arraybackslash}"
)
col_defs_i <-
paste0(
align,
"p{",
create_singlecolumn_width_text_l(pt = colwidth_df$pt[i], lw = colwidth_df$lw[i]),
"}"
)
}
col_defs <- c(col_defs, col_defs_i)
}
} else {
col_defs <- substr(col_alignment, 1, 1)
}
because col_alignment
only contains visible columns whereas colwidth_df
contains both visible and invisible columns. A fix would be to get rid of the invisible columns of colwidth_df
:
if (any(colwidth_df$unspec < 1L)) {
col_defs <- NULL
colwidth_df_visible <- colwidth_df[colwidth_df$type != "hidden", ]
for (i in seq_along(col_alignment)) {
if (colwidth_df_visible$unspec[i] == 1L) {
col_defs_i <- substr(col_alignment[i], 1, 1)
} else {
align <-
switch(
col_alignment[i],
left = ">{\\raggedright\\arraybackslash}",
right = ">{\\raggedleft\\arraybackslash}",
center = ">{\\centering\\arraybackslash}",
">{\\raggedright\\arraybackslash}"
)
col_defs_i <-
paste0(
align,
"p{",
create_singlecolumn_width_text_l(pt = colwidth_df_visible$pt[i], lw = colwidth_df_visible$lw[i]),
"}"
)
}
col_defs <- c(col_defs, col_defs_i)
}
} else {
col_defs <- substr(col_alignment, 1, 1)
}
EDIT: The above doesn't work with stubs/row_groups introduced with the rowname_col
and groupname_col
options:
data <- mtcars[1:4, c("am", "gear", "mpg", "cyl", "disp")] |>
gt(rowname_col = "gear", groupname_col = "am") |>
cols_merge(
columns = c("mpg", "cyl")
) |>
cols_width(
"gear" ~ px(50),
c("mpg", "disp") ~ px(150)
)
yields
> colwidth_df
type unspec lw pt tbl_width
1 row_group 1 0 0.0 NA
2 stub 0 0 37.5 NA
3 default 0 0 112.5 NA
4 hidden 1 0 0.0 NA
5 default 0 0 112.5 NA
Thanks both for your investigation!
Basically, if you use cols_merge(c(col1, col2))
, under the hood, gt does the merging, and keeps col1 as the new column and calls cols_hide()
on col2.
We'd happily accept a PR for this with tests, clear explanations, before and after screenshots of the result
@olivroy: I'm taking a look at this and currently trying to understand stub layouts. Could you give me an example where the result of get_stub_layout()
has length 2? I can't think of such an example, but from the code it seems possible, and I'd like to handle all cases properly.
get_stub_layout()
returns length 2 if you have both row_group_as_column = TRUE
and the data has row names
Description
Widths set with
cols_width()
isn't respected when usingcols_merge()
and when the output is PDF.Reproducible example
Consider this Quarto document:
Expected result
The table created doesn't respect the widths set:
When output as html, everything looks fine:
Session info