Skip to content

feat: allow arbitrary number of columns in stub#2008

Merged
rich-iannone merged 38 commits intomasterfrom
feat-multiple-cols-in-stub
Jul 25, 2025
Merged

feat: allow arbitrary number of columns in stub#2008
rich-iannone merged 38 commits intomasterfrom
feat-multiple-cols-in-stub

Conversation

@rich-iannone
Copy link
Copy Markdown
Member

@rich-iannone rich-iannone commented Jul 7, 2025

This PR adds functionality for having several columns become part of the stub. It will allow for stubs where there are levels of headers for row labels (much in the same way that spanners can be layered over column labels). Here's an example where three columns are part of the stub:

image

Since this feature breaks many assumptions in the table-building logic (i.e., a stub only has one column, but two if gt(.., row_group_as_column = TRUE)) there may some instability during the time when this is merged and when the package is updated in CRAN. Things that need to be done (and checked closely) are:

  • tab_stubhead() works properly with a multi-column stub; documentation should be updated
  • tab_style() and tab_footnote() works with multi-column stubs
  • cells_stub() is updated with a columns= parameter and works with the above functions
  • tab_row_group() works with multi-column stubs
  • all existing functionality and tests work when there is no stub or a one-column stub (along with row groups)
  • tables with multi-column stubs render well with all output formats
  • formatting works okay with columns in a multi-column stub
  • summary rows not adversely affected by a multi-column stub

The above considerations may not all be covered by this PR, but addressed in follow-up PRs. And there may be other bugs discovered during that phase.

Fixes: #601
Fixes: #918
Fixes: #1406
Fixes: #1408

@olivroy
Copy link
Copy Markdown
Collaborator

olivroy commented Jul 10, 2025

Hi Rich! this looks promising! Looking forward to helping test the new feature!

Just an FYi, as you said this may be a risky move, this PR only has a 43% test coverage. If possible, I think adding a few tests would be worthwhile!

edit: apologies. Just saw that you aren’t done yet and haven’t started the testing part oops 😬

@rich-iannone
Copy link
Copy Markdown
Member Author

@olivroy this is definitely a big feature and I’ve been taking my time with it since so many things can be broken with this (fixed many small issues so far!).

So far I’ve done a lot of manual/visual testing on my own computer. But yeah, there will be some tests submitted soon!

Thanks for offering to test this all out! I imagine things will still be rough after this is merged and several follow-up fixes will need to be made before release.

@rich-iannone rich-iannone marked this pull request as draft July 10, 2025 18:30
@olivroy olivroy closed this Jul 10, 2025
@olivroy olivroy reopened this Jul 10, 2025
@olivroy
Copy link
Copy Markdown
Collaborator

olivroy commented Jul 10, 2025

this is great! sorry, accidentally hit the close PR button

@rich-iannone rich-iannone marked this pull request as ready for review July 25, 2025 17:44
@rich-iannone
Copy link
Copy Markdown
Member Author

I've made the internal vertical lines of the stub 1px now because it didn't quite look right before with the 2px lines. So now this code

library(gt)

df = dplyr::tibble(
    vals = 1:8,
    rowname_left  = c("A",  "A",  "A",  "A",  "B",  "B",  "B",  "B"),
    rowname_mid   = c("AA", "AA", "AZ", "AZ", "BA", "BA", "BZ", "BZ"),
    rowname_right = c("H", "I", "J", "K", "L", "M", "N", "O")
)

gt(
    df,
    rowname_col = c("rowname_left", "rowname_mid", "rowname_right")
) |> tab_stubhead(c("left", "middle", "right"))

generates this table:

image

@rich-iannone
Copy link
Copy Markdown
Member Author

rich-iannone commented Jul 25, 2025

Styling works! But it's not perfect. You can style components of the multicolumn stub:

library(gt)

df = dplyr::tibble(
    vals = 1:8,
    rowname_left  = c("A",  "A",  "A",  "A",  "B",  "B",  "B",  "B"),
    rowname_mid   = c("AA", "AA", "AZ", "AZ", "BA", "BA", "BZ", "BZ"),
    rowname_right = c("H", "I", "J", "K", "L", "M", "N", "O")
)

gt(
    df,
    rowname_col = c("rowname_left", "rowname_mid", "rowname_right")
) |> 
  tab_stubhead(c("left", "middle", "right")) |>
  tab_style(
    style = list(cell_fill(color="steelblue"), cell_text(color="white")),
    locations = cells_stub(columns = "rowname_mid", rows = c(1, 5))
  )

and get this:

image

However, the row indices have to currently match the 'group leaders' (odd numbered rows in the "rowname_mid" column). So, using rows = 2 won't apply the style to the 'AA' cell.

Thankfully you can target stub rows by their names so this works to produce the same result as above:

... |>
tab_style(
    style = list(cell_fill(color="steelblue"), cell_text(color="white")),
    locations = cells_stub(columns = "rowname_mid", rows = c("AA", "BA"))
  )

There are going to be issues if there are duplicate names. This is something to address more fully later, I think.

@rich-iannone rich-iannone merged commit cc8f8d0 into master Jul 25, 2025
12 checks passed
@rich-iannone rich-iannone deleted the feat-multiple-cols-in-stub branch July 25, 2025 18:04
@Nova-Scotia Nova-Scotia mentioned this pull request Aug 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Collapse rows Ability to add multiple stubhead labels when row_group.as_column = TRUE Multiple rowname cols entry Spanner row

2 participants