Skip to content

Add modify_split_caption() to label paginated splits and hide the split column (#282)#283

Open
Melkiades wants to merge 8 commits into
mainfrom
282_modify_split_caption@main
Open

Add modify_split_caption() to label paginated splits and hide the split column (#282)#283
Melkiades wants to merge 8 commits into
mainfrom
282_modify_split_caption@main

Conversation

@Melkiades

Copy link
Copy Markdown
Contributor

What changes are proposed in this pull request?

When a listing is paginated with gtsummary::tbl_split_by_rows(variable_level = <col>) (e.g. a lab listing split by PARAM, or a demographics listing split by treatment), two post-processing steps were previously repeated inline in every template: prefixing the split level for the page caption/subtitle, and hiding the redundant split column. modify_split_caption() bundles both:

tbl_listing(df, split_by_rows = list(variable_level = "PARAM")) |>
  modify_split_caption(spl_col = "PARAM")
# -> each page caption "Parameter: <level>"; PARAM column hidden
  • pattern is a single glue string ({spl_level} is the split value); default suits BDS/lab tables.
  • hide_spl_col = TRUE by default; silent when the column is absent or already hidden.
  • Works on a single split element or the whole tbl_split list; row-number splits (no variable_level) are skipped.
  • Keeps the gtsummary-native variable_level attribute in sync with the caption, so decorators that read it (e.g. citril) show the same text — no external dependency added.

Co-located in R/tbl_listing.R under @rdname tbl_listing, next to remove_duplicate_keys().

Reference GitHub issue associated with pull request. closes #282


Pre-review Checklist (if item does not apply, mark is as complete)

  • All GitHub Action workflows pass with a ✅
  • PR branch has pulled the most recent updates from master branch: usethis::pr_merge_main()
  • If a bug was fixed, a unit test was added.
  • Code coverage is suitable for any new functions/features (generally, 100% coverage for new code): devtools::test_coverage()
  • Request a reviewer

Reviewer Checklist (if item does not apply, mark is as complete)

  • If a bug was fixed, a unit test was added.
  • Run pkgdown::build_site(). Check the R console for errors, and review the rendered website.
  • Code coverage is suitable for any new functions/features: devtools::test_coverage()

When the branch is ready to be merged:

  • Update NEWS.md with the changes from this pull request under the heading "# crane (development version)". If there is an issue associated with the pull request, reference it in parentheses at the end update (see NEWS.md for examples).
  • All GitHub Action workflows pass with a ✅
  • Approve Pull Request
  • Merge the PR. Please use "Squash and merge" or "Rebase and merge".

…282)

Post-process a tbl_split listing so each page carries a caption built
from its split level via a glue pattern (default 'Parameter: {spl_level}',
suited to lab listings split by PARAM) and the now-redundant split
column is hidden.

- Operates on a single split element or the whole list.
- Keeps the gtsummary-native variable_level attribute in sync so
  decorators that read it show the same caption.
- Hiding is silent when the column is absent or already hidden; pages
  from row-number splits (no variable_level) are skipped.

Co-located in R/tbl_listing.R under @Rdname tbl_listing with
remove_duplicate_keys().
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Unit Tests Summary

  1 files  267 suites   3m 30s ⏱️
267 tests 267 ✅ 0 💤 0 ❌
783 runs  783 ✅ 0 💤 0 ❌

Results for commit 213b972.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Unit Test Performance Difference

Test Suite $Status$ Time on main $±Time$ $±Tests$ $±Skipped$ $±Failures$ $±Errors$
modify_split_caption 👶 $+0.00$ $+3$ $0$ $0$ $0$
Additional test case details
Test Suite $Status$ Time on main $±Time$ Test Case
add_forest 💚 $3.52$ $-1.27$ add_forest_table_engine_flextable_works
add_hierarchical_count_row 💔 $0.32$ $+1.40$ add_hierarchical_count_row_works
adjust_stat_columns_wrap 💚 $1.80$ $-1.46$ adjust_stat_columns_wrap_validates_input_correctly
annotate_gg 💔 $3.54$ $+1.80$ annotate_lineplot_df_warns_if_plot_is_not_generated_by_gg_lineplot
annotate_gg_pkc 💚 $3.12$ $-2.05$ annotate_pkc_df_warns_when_given_a_standard_ggplot_object
gg_km 💔 $0.05$ $+1.01$ gg_km_works_and_handles_annotations_correctly
modify_split_caption 👶 $+0.00$ modify_split_caption_checks_its_inputs
modify_split_caption 👶 $+0.00$ modify_split_caption_hide_spl_col_FALSE_keeps_the_split_column
modify_split_caption 👶 $+0.00$ modify_split_caption_honors_a_custom_glue_pattern
modify_split_caption 👶 $+0.00$ modify_split_caption_is_silent_when_the_column_is_absent_or_already_hidden
modify_split_caption 👶 $+0.43$ modify_split_caption_labels_each_page_and_hides_the_split_column
modify_split_caption 👶 $+0.00$ modify_split_caption_skips_row_number_splits_that_lack_a_level
modify_split_caption 👶 $+0.00$ modify_split_caption_works_on_a_single_non_list_split_element
tbl_hierarchical_rate_by_grade 💚 $23.39$ $-22.26$ tbl_hierarchical_rate_by_grade_works
tbl_roche_subgroups 💔 $1.23$ $+23.14$ tbl_roche_subgroups_time_to_event_NULL_works
tbl_shift 💚 $3.85$ $-1.00$ tbl_shift_strata_location_
tbl_with_pools 💔 $12.64$ $+1.88$ tbl_with_pools_validates_inputs_correctly

Results for commit 62e61af

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

badge

Code Coverage Summary

Filename                                 Stmts    Miss  Cover    Missing
-------------------------------------  -------  ------  -------  ------------------------------------------------------------------------------------------------
R/add_blank_rows.R                          63       0  100.00%
R/add_difference_row.R                     101       0  100.00%
R/add_forest_utils.R                        97      10  89.69%   76-79, 94-100
R/add_forest.R                             139       0  100.00%
R/add_hierarchical_count_row.R              33       0  100.00%
R/adjust_stat_columns_wrap.R                29       1  96.55%   59
R/annotate_gg_km.R                         141       0  100.00%
R/annotate_gg_pkc.R                         92       0  100.00%
R/annotate_gg.R                             81       0  100.00%
R/ard_tabulate_abnormal_by_baseline.R       65       0  100.00%
R/crane-package.R                            2       2  0.00%    26-27
R/deprecated.R                              21      21  0.00%    18-54
R/df_add_poolings.R                         41       0  100.00%
R/get_cox_pairwise_df.R                    163       0  100.00%
R/gg_km_utils.R                             39      14  64.10%   20-37
R/gg_km.R                                  143      37  74.13%   55-58, 75, 102, 176-181, 184-187, 197-199, 204-205, 239-241, 248-251, 255, 266-270, 283, 285-287
R/gg_lineplot.R                             94       0  100.00%
R/gg_mmrm_lineplot.R                       102       1  99.02%   106
R/gg_pkc_lineplot.R                         98       0  100.00%
R/gg_utils.R                               221       0  100.00%
R/label_roche.R                             72       0  100.00%
R/modify_header_rm_md.R                     18       2  88.89%   35-36
R/modify_split_caption.R                    26       0  100.00%
R/modify_zero_recode.R                      20       1  95.00%   64
R/reverse_difference_ci.R                   33       0  100.00%
R/tbl_baseline_chg.R                       188       0  100.00%
R/tbl_coxph.R                               90       1  98.89%   229
R/tbl_hierarchical_incidence_rate.R        291       4  98.63%   430-433
R/tbl_hierarchical_rate_and_count.R        339      13  96.17%   343, 425, 446-456
R/tbl_hierarchical_rate_by_grade.R         317       3  99.05%   169-171
R/tbl_listing.R                             35       0  100.00%
R/tbl_mmrm.R                               254       1  99.61%   393
R/tbl_null_report.R                          9       0  100.00%
R/tbl_rmpt.R                               157      12  92.36%   299-304, 316-321
R/tbl_roche_subgroups.R                    155       0  100.00%
R/tbl_roche_summary.R                       64       0  100.00%
R/tbl_shift.R                              116       0  100.00%
R/tbl_survfit_quantiles.R                  154       0  100.00%
R/tbl_survfit_times.R                       92       0  100.00%
R/tbl_with_pools.R                          64       0  100.00%
R/theme_gtsummary_roche.R                   87       1  98.85%   61
R/utils.R                                   42       0  100.00%
TOTAL                                     4388     124  97.17%

Diff against main

Filename                    Stmts    Miss  Cover
------------------------  -------  ------  --------
R/modify_split_caption.R      +26       0  +100.00%
TOTAL                         +26       0  +0.02%

Results for commit: 213b972

Minimum allowed coverage is 80%

♻️ This comment has been updated with latest results

Melkiades and others added 3 commits July 2, 2026 07:41
Move modify_split_caption() out of the tbl_listing help page into its
own R/modify_split_caption.R with a standalone doc page, since it applies
to any split {gtsummary} table, not just listings. Add @Seealso
cross-links and usage examples to the commonly-split tbl_* functions
(tbl_listing, tbl_baseline_chg, tbl_shift) and move its tests to a
dedicated test-modify_split_caption.R.

@llrs-roche llrs-roche left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if expected but on Rstudio when visualizing this split I see this:

Image

What it is surprising is that the pattern is at the center of the table. I'm not sure how it is on other formats but might be worth checking

Comment thread R/modify_split_caption.R Outdated
Comment thread R/modify_split_caption.R
Comment thread R/modify_split_caption.R Outdated
Comment thread tests/testthat/test-modify_split_caption.R
Comment thread R/modify_split_caption.R Outdated
Comment thread R/modify_split_caption.R Outdated
Comment thread R/modify_split_caption.R Outdated
Melkiades and others added 2 commits July 3, 2026 10:44
Co-authored-by: Lluís Revilla <185338939+llrs-roche@users.noreply.github.com>
Signed-off-by: Davide Garolini <dgarolini@gmail.com>
- move argument checks above the list map so a list of split tables is
  validated once up front
- use all(spl_col %in% ...) in the hide condition, matching all_of() below
- shorten and focus the examples on the new function
- assert caption, variable_level and hide flag on every page
@Melkiades

Copy link
Copy Markdown
Contributor Author

On the centered caption: that's the renderer's default, not something this function sets -- we just call gtsummary::modify_caption() and the alignment comes from how each backend prints the caption. Worth checking how it lands in docx/flextable (the actual target format) separately; I'd rather not special-case alignment inside modify_split_caption().

Melkiades added 2 commits July 3, 2026 10:53
Writing both a caption and the variable_level subtitle duplicated the
text after decoration with citril::decorate_tlg(). Set only the native
variable_level attribute so decorators render it once as a page subtitle.
Set the split label as a gtsummary caption in addition to the
variable_level attribute. The caption renders inside the table's
<caption> element so the subtitle is visible when a split page is
printed on its own, while variable_level lets reporting engines promote
the same text to a dedicated subtitle row.
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.

Add modify_split_caption() to label paginated splits and hide the split column

2 participants