Attach a subgroup_spec to a tabular_spec. At render time the
engine partitions spec@data by the unique values of by,
runs the full resolve pipeline per group, and concatenates the
results. A hard page break is inserted between groups —
every subgroup value starts on its own page. A centred banner
line appears above the column-header rule on every page of the
group (including continuation pages), matching the canonical
submission page-layout convention.
Arguments
- .spec
The
tabular_specto partition.<tabular_spec>: required.- by
Column name(s) to partition by.
<character>: required. Must reference a column inspec@data. Length-0 (orcharacter(0)) clears the partition. Matches theby =arg convention ofsort_rows().Multi-variable. Pass
c("var1", "var2")to cross on every combination present in the data. Multi-var partitions require an explicitlabeltemplate (the single-var auto-default does not generalise).- label
Banner template.
<character(1) | NULL>: default NULL. Glue-style template with{column_name}placeholders.NULLderives a default from the partition variable'sattr(data[[by]], "label")(falling back to the column name).Tip: reference auxiliary columns to inline the BigN or any qualifier that is constant within group — e.g.
"Cohort: {cohort} (N = {n})".Restriction: Every
{col}reference must be a column inspec@data. Unknown columns raisetabular_error_subgroup_template_unknown_col.- big_n
Per-page BigN denominators.
<data.frame> | NULL: default NULL. A table giving the(N=x)denominator each arm's header should show on each subgroup page. Each arm is named as it appears in the header — either a data column (the N rides that column's leaf label) or aheaders()band label (the N rides that spanner band). Ns are non-negative whole numbers; provide one perbycombination present in the data. Accepts either shape:Wide — the
bycolumn(s) plus one numeric column per arm (cells are the Ns).Long — the
bycolumn(s) plus one arm-name column and one numeric N column, i.e.dplyr::count()/summarise()output used directly with no reshaping.
# Wide: one column per arm. wide <- tibble::tribble( ~sex, ~placebo, ~drug_50, ~Total, "F", 24L, 9L, 42L, "M", 18L, 15L, 47L ) # Long: count()-style, pivoted internally. Equivalent to `wide`. long <- tibble::tribble( ~sex, ~arm, ~n, "F", "placebo", 24L, "F", "drug_50", 9L, "F", "Total", 42L, "M", "placebo", 18L, "M", "drug_50", 15L, "M", "Total", 47L ) spec |> subgroup(by = "sex", big_n = long)Requirement: band keying needs
headers()beforesubgroup()in the pipeline; each arm name must resolve to exactly one leaf XOR one band. Every missing per-page N is a call-time error, never a silently wrong denominator.Note: the per-arm N renders in every backend. The paged backends (RTF, PDF / LaTeX, DOCX) carry it on the column header that repeats on every page of the subgroup. HTML and Markdown are continuous (one stacked table, one header), so they instead emit a per-arm N row directly under each subgroup banner, the
(N=x)aligned beneath its arm column.- big_n_fmt
Per-page BigN template.
<character(1)>: default "\n(N={n})". Appended to each arm's header label, with{n}substituted by that page/column's integer N. Only the{n}token is allowed; the default puts the N on its own line under the arm name.
Details
Label is a glue-style template. When label carries
{col} placeholders, the engine substitutes each placeholder
against the FIRST ROW of the group's filtered data — so any
column whose value is constant within group (BigN, cohort
descriptor, qualifier text) can ride into the banner. Columns
that vary within group also resolve, but always to the first
row's value; pre-compute aggregates upstream.
Default label (when label = NULL, single var): the engine
generates "<attr(data[[by]], 'label') %||% by>: {<by>}",
so subgroup(by = "cohort") renders banners like "Cohort: A"
and "Cohort: B" without further configuration.
Replace, not stack. A second subgroup() call REPLACES the
prior partition — subgroup is a single spec, not a stackable
list. Passing by = character(0) clears the slot, though
typical clinical pipelines set the partition once up front.
Display-side only. subgroup() partitions a pre-summarised
wide data frame; it does not aggregate, filter, or weight. The
user supplies one summary row per displayed row per group;
tabular's job is solely to lay them out with the per-group
banner and page break.
Multi-variable crossing. by = c("SEX", "AGEGR1") partitions
on every combination present in the data (first variable varies
slowest, matching expand.grid() convention). An explicit
label template is required for multi-var partitions since the
single-var default "<var>: {<var>}" does not generalise; raise
tabular_error_subgroup_label_required otherwise.
Auto-hide of partition + template columns. Every column named
in by, plus every column referenced via a {col} placeholder
in label, automatically flips to visible = FALSE at engine
time. Users do not restate col_spec(visible = FALSE) inside
cols() for these columns — mirroring the
col_spec(indent = ...) auto-hide ergonomic.
See also
Pipeline siblings: sort_rows(), paginate().
Examples
# ---- Example 1: Vital signs split into one page set per sex ----
#
# The simplest partition: a single clinical variable. Each `sex`
# value gets its own page set with a centred `Sex: <value>` banner
# above the column-header rule on every page, separated by hard page
# breaks. With no `label` template the banner uses the variable's
# `label` attribute when present (set here), falling back to the
# column name. Within each page, parameter nests visit nests the
# statistic rows.
vs <- cdisc_saf_subgroup
attr(vs$sex, "label") <- "Sex"
tabular(
vs,
titles = c(
"Table 14.2.1",
"Vital Signs by Visit",
"Safety Population"
),
footnotes = "Descriptive statistics by treatment arm."
) |>
cols(
sex_n = col_spec(visible = FALSE),
paramcd = col_spec(visible = FALSE),
param = col_spec(usage = "group", label = "Parameter"),
visit = col_spec(usage = "group", label = "Visit"),
stat_label = col_spec(label = "Statistic"),
placebo = col_spec(label = "Placebo", align = "decimal"),
drug_50 = col_spec(label = "Drug 50", align = "decimal"),
drug_100 = col_spec(label = "Drug 100", align = "decimal"),
Total = col_spec(label = "Total", align = "decimal")
) |>
subgroup(by = "sex")
Table 14.2.1
Vital Signs by Visit
Safety Population
Statistic Placebo Drug 50 Drug 100 Total Sex: F Diastolic BP (mmHg) Baseline n 208 220 140 568 Mean (SD) 77.1 (11.2) 76.3 (10.5) 78.0 (10.8) 77.0 (10.8) Median 78.0 77.3 78.3 78.0 Min, Max 40 , 110 48 , 100 51 , 108 40 , 110 Week 8 n 168 148 104 420 Mean (SD) 75.1 (9.4) 77.1 (11.0) 76.0 (10.0) 76.0 (10.1) Median 76.0 79.7 78.0 78.0 Min, Max 49 , 98 55 , 98 54 , 98 49 , 98 Week 16 n 156 100 68 324 Mean (SD) 74.9 (11.1) 75.6 (10.8) 77.8 (8.9) 75.8 (10.6) Median 77.7 76.0 79.0 78.0 Min, Max 49 , 98 55 , 98 56 , 92 49 , 98 End of Treatment n 129 108 81 318 Mean (SD) 74.0 (10.7) 77.2 (11.9) 76.5 (11.7) 75.7 (11.5) Median 74.0 79.5 80.0 78.0 Min, Max 49 , 100 50 , 100 56 , 98 49 , 100 Systolic BP (mmHg) Baseline n 208 220 140 568 Mean (SD) 141.1 (16.9) 139.2 (18.2) 140.4 (19.5) 140.2 (18.0) Median 141.8 140.0 140.0 140.0 Min, Max 100 , 184 100 , 194 100 , 192 100 , 194 Week 8 n 168 148 104 420 Mean (SD) 138.1 (16.5) 137.9 (17.8) 139.6 (19.0) 138.4 (17.6) Median 139.5 135.7 140.0 138.7 Min, Max 100 , 184 92 , 200 91 , 198 91 , 200 Week 16 n 156 100 68 324 Mean (SD) 137.9 (17.4) 134.8 (15.0) 142.0 (15.3) 137.8 (16.4) Median 139.5 130.5 140.0 138.0 Min, Max 106 , 190 100 , 168 107 , 186 100 , 190 End of Treatment n 129 108 81 318 Sex: F Mean (SD) 135.8 (15.3) 137.0 (16.1) 138.0 (17.4) 136.8 (16.1) Median 133.0 133.0 140.0 136.0 Min, Max 95 , 172 98 , 178 100 , 177 95 , 178 Sex: M Diastolic BP (mmHg) Baseline n 132 164 148 444 Mean (SD) 77.1 (10.0) 77.1 (8.8) 78.5 (9.8) 77.6 (9.5) Median 76.0 76.3 80.0 76.8 Min, Max 54 , 102 58 , 108 58 , 100 54 , 108 Week 8 n 124 92 120 336 Mean (SD) 75.4 (8.8) 72.7 (9.3) 78.5 (8.1) 75.8 (9.0) Median 76.0 72.0 79.7 76.0 Min, Max 50 , 101 52 , 100 57 , 94 50 , 101 Week 16 n 116 68 80 264 Mean (SD) 75.4 (10.7) 74.6 (8.7) 74.5 (8.8) 74.9 (9.7) Median 76.0 73.7 75.5 75.3 Min, Max 50 , 98 59 , 94 50 , 90 50 , 98 End of Treatment n 93 69 87 249 Mean (SD) 75.1 (10.6) 74.0 (9.6) 75.6 (7.8) 75.0 (9.4) Median 73.0 74.0 76.0 74.0 Min, Max 58 , 104 52 , 94 57 , 90 52 , 104 Systolic BP (mmHg) Baseline n 132 164 148 444 Mean (SD) 130.0 (16.5) 136.1 (18.7) 135.3 (14.4) 134.0 (16.9) Median 130.3 134.0 137.2 132.0 Min, Max 80 , 170 100 , 188 104 , 170 80 , 188 Week 8 n 124 92 120 336 Mean (SD) 133.7 (17.5) 130.1 (16.9) 131.2 (10.3) 131.8 (15.2) Median 131.0 131.0 131.2 131.0 Min, Max 90 , 189 98 , 180 110 , 158 90 , 189 Week 16 n 116 68 80 264 Mean (SD) 130.2 (18.6) 129.0 (12.5) 126.5 (12.8) 128.8 (15.6) Median 130.0 129.7 126.0 128.0 Min, Max 76 , 178 100 , 158 99 , 154 76 , 178 End of Treatment n 93 69 87 249 Sex: M Mean (SD) 128.5 (14.7) 126.8 (16.8) 127.0 (11.6) 127.5 (14.3) Median 130.0 124.0 130.0 130.0 Min, Max 78 , 164 92 , 162 100 , 156 78 , 164
Descriptive statistics by treatment arm.
# ---- Example 2: Partition by Sex with inline BigN via template ----
#
# `label` is a glue-style template; any column whose value is
# constant within group can ride into the banner. `cdisc_saf_subgroup`
# ships a partition-constant `sex_n` BigN column alongside the value
# cells, so each banner reads `"Sex: F (N = 143)"`, etc. `sex` and
# `sex_n` auto-hide from the body (partition `by` and template-
# referenced columns).
tabular(cdisc_saf_subgroup, titles = "Vital Signs by Visit") |>
cols(
paramcd = col_spec(visible = FALSE),
param = col_spec(usage = "group", label = "Parameter"),
visit = col_spec(usage = "group", label = "Visit"),
stat_label = col_spec(label = "Statistic"),
placebo = col_spec(label = "Placebo", align = "decimal"),
drug_50 = col_spec(label = "Drug 50", align = "decimal"),
drug_100 = col_spec(label = "Drug 100", align = "decimal"),
Total = col_spec(label = "Total", align = "decimal")
) |>
subgroup(by = "sex", label = "Sex: {sex} (N = {sex_n})")
Vital Signs by Visit
Statistic Placebo Drug 50 Drug 100 Total Sex: F (N = 143) Diastolic BP (mmHg) Baseline n 208 220 140 568 Mean (SD) 77.1 (11.2) 76.3 (10.5) 78.0 (10.8) 77.0 (10.8) Median 78.0 77.3 78.3 78.0 Min, Max 40 , 110 48 , 100 51 , 108 40 , 110 Week 8 n 168 148 104 420 Mean (SD) 75.1 (9.4) 77.1 (11.0) 76.0 (10.0) 76.0 (10.1) Median 76.0 79.7 78.0 78.0 Min, Max 49 , 98 55 , 98 54 , 98 49 , 98 Week 16 n 156 100 68 324 Mean (SD) 74.9 (11.1) 75.6 (10.8) 77.8 (8.9) 75.8 (10.6) Median 77.7 76.0 79.0 78.0 Min, Max 49 , 98 55 , 98 56 , 92 49 , 98 End of Treatment n 129 108 81 318 Mean (SD) 74.0 (10.7) 77.2 (11.9) 76.5 (11.7) 75.7 (11.5) Median 74.0 79.5 80.0 78.0 Min, Max 49 , 100 50 , 100 56 , 98 49 , 100 Systolic BP (mmHg) Baseline n 208 220 140 568 Mean (SD) 141.1 (16.9) 139.2 (18.2) 140.4 (19.5) 140.2 (18.0) Median 141.8 140.0 140.0 140.0 Min, Max 100 , 184 100 , 194 100 , 192 100 , 194 Week 8 n 168 148 104 420 Mean (SD) 138.1 (16.5) 137.9 (17.8) 139.6 (19.0) 138.4 (17.6) Median 139.5 135.7 140.0 138.7 Min, Max 100 , 184 92 , 200 91 , 198 91 , 200 Week 16 n 156 100 68 324 Mean (SD) 137.9 (17.4) 134.8 (15.0) 142.0 (15.3) 137.8 (16.4) Median 139.5 130.5 140.0 138.0 Min, Max 106 , 190 100 , 168 107 , 186 100 , 190 End of Treatment n 129 108 81 318 Mean (SD) 135.8 (15.3) 137.0 (16.1) 138.0 (17.4) 136.8 (16.1) Median 133.0 133.0 140.0 136.0 Min, Max 95 , 172 98 , 178 100 , 177 95 , 178 Sex: M (N = 111) Diastolic BP (mmHg) Baseline n 132 164 148 444 Mean (SD) 77.1 (10.0) 77.1 (8.8) 78.5 (9.8) 77.6 (9.5) Median 76.0 76.3 80.0 76.8 Min, Max 54 , 102 58 , 108 58 , 100 54 , 108 Week 8 n 124 92 120 336 Mean (SD) 75.4 (8.8) 72.7 (9.3) 78.5 (8.1) 75.8 (9.0) Median 76.0 72.0 79.7 76.0 Min, Max 50 , 101 52 , 100 57 , 94 50 , 101 Week 16 n 116 68 80 264 Mean (SD) 75.4 (10.7) 74.6 (8.7) 74.5 (8.8) 74.9 (9.7) Median 76.0 73.7 75.5 75.3 Min, Max 50 , 98 59 , 94 50 , 90 50 , 98 End of Treatment n 93 69 87 249 Mean (SD) 75.1 (10.6) 74.0 (9.6) 75.6 (7.8) 75.0 (9.4) Median 73.0 74.0 76.0 74.0 Min, Max 58 , 104 52 , 94 57 , 90 52 , 104 Systolic BP (mmHg) Baseline n 132 164 148 444 Mean (SD) 130.0 (16.5) 136.1 (18.7) 135.3 (14.4) 134.0 (16.9) Median 130.3 134.0 137.2 132.0 Min, Max 80 , 170 100 , 188 104 , 170 80 , 188 Week 8 n 124 92 120 336 Mean (SD) 133.7 (17.5) 130.1 (16.9) 131.2 (10.3) 131.8 (15.2) Median 131.0 131.0 131.2 131.0 Min, Max 90 , 189 98 , 180 110 , 158 90 , 189 Week 16 n 116 68 80 264 Mean (SD) 130.2 (18.6) 129.0 (12.5) 126.5 (12.8) 128.8 (15.6) Median 130.0 129.7 126.0 128.0 Min, Max 76 , 178 100 , 158 99 , 154 76 , 178 End of Treatment n 93 69 87 249 Mean (SD) 128.5 (14.7) 126.8 (16.8) 127.0 (11.6) 127.5 (14.3) Median 130.0 124.0 130.0 130.0 Min, Max 78 , 164 92 , 162 100 , 156 78 , 164
# ---- Example 3: Multi-variable crossing (Sex x Visit) ----
#
# Pass two columns to partition on every combination present in the
# data. The label template MUST reference each variable explicitly
# because the single-var auto-default does not generalise. The cross
# varies the first column (sex) slowest and the second (visit)
# fastest, giving page sequence F/Baseline, F/Week 8, ..., M/Baseline,
# ... Parameter nests the statistic rows within each page.
tabular(cdisc_saf_subgroup, titles = "Vital Signs by Sex and Visit") |>
cols(
sex_n = col_spec(visible = FALSE),
paramcd = col_spec(visible = FALSE),
param = col_spec(usage = "group", label = "Parameter"),
stat_label = col_spec(label = "Statistic"),
placebo = col_spec(label = "Placebo", align = "decimal"),
drug_50 = col_spec(label = "Drug 50", align = "decimal"),
drug_100 = col_spec(label = "Drug 100", align = "decimal"),
Total = col_spec(label = "Total", align = "decimal")
) |>
subgroup(
by = c("sex", "visit"),
label = "Sex: {sex} / Visit: {visit}"
)
Vital Signs by Sex and Visit
Statistic Placebo Drug 50 Drug 100 Total Sex: F / Visit: Baseline Diastolic BP (mmHg) n 208 220 140 568 Mean (SD) 77.1 (11.2) 76.3 (10.5) 78.0 (10.8) 77.0 (10.8) Median 78.0 77.3 78.3 78.0 Min, Max 40 , 110 48 , 100 51 , 108 40 , 110 Systolic BP (mmHg) n 208 220 140 568 Mean (SD) 141.1 (16.9) 139.2 (18.2) 140.4 (19.5) 140.2 (18.0) Median 141.8 140.0 140.0 140.0 Min, Max 100 , 184 100 , 194 100 , 192 100 , 194 Sex: F / Visit: Week 8 Diastolic BP (mmHg) n 168 148 104 420 Mean (SD) 75.1 (9.4) 77.1 (11.0) 76.0 (10.0) 76.0 (10.1) Median 76.0 79.7 78.0 78.0 Min, Max 49 , 98 55 , 98 54 , 98 49 , 98 Systolic BP (mmHg) n 168 148 104 420 Mean (SD) 138.1 (16.5) 137.9 (17.8) 139.6 (19.0) 138.4 (17.6) Median 139.5 135.7 140.0 138.7 Min, Max 100 , 184 92 , 200 91 , 198 91 , 200 Sex: F / Visit: Week 16 Diastolic BP (mmHg) n 156 100 68 324 Mean (SD) 74.9 (11.1) 75.6 (10.8) 77.8 (8.9) 75.8 (10.6) Median 77.7 76.0 79.0 78.0 Min, Max 49 , 98 55 , 98 56 , 92 49 , 98 Systolic BP (mmHg) n 156 100 68 324 Mean (SD) 137.9 (17.4) 134.8 (15.0) 142.0 (15.3) 137.8 (16.4) Median 139.5 130.5 140.0 138.0 Min, Max 106 , 190 100 , 168 107 , 186 100 , 190 Sex: F / Visit: End of Treatment Diastolic BP (mmHg) n 129 108 81 318 Mean (SD) 74.0 (10.7) 77.2 (11.9) 76.5 (11.7) 75.7 (11.5) Median 74.0 79.5 80.0 78.0 Min, Max 49 , 100 50 , 100 56 , 98 49 , 100 Systolic BP (mmHg) n 129 108 81 318 Mean (SD) 135.8 (15.3) 137.0 (16.1) 138.0 (17.4) 136.8 (16.1) Median 133.0 133.0 140.0 136.0 Min, Max 95 , 172 98 , 178 100 , 177 95 , 178 Sex: M / Visit: Baseline Diastolic BP (mmHg) n 132 164 148 444 Mean (SD) 77.1 (10.0) 77.1 (8.8) 78.5 (9.8) 77.6 (9.5) Median 76.0 76.3 80.0 76.8 Min, Max 54 , 102 58 , 108 58 , 100 54 , 108 Systolic BP (mmHg) n 132 164 148 444 Mean (SD) 130.0 (16.5) 136.1 (18.7) 135.3 (14.4) 134.0 (16.9) Median 130.3 134.0 137.2 132.0 Min, Max 80 , 170 100 , 188 104 , 170 80 , 188 Sex: M / Visit: Week 8 Diastolic BP (mmHg) n 124 92 120 336 Mean (SD) 75.4 (8.8) 72.7 (9.3) 78.5 (8.1) 75.8 (9.0) Median 76.0 72.0 79.7 76.0 Min, Max 50 , 101 52 , 100 57 , 94 50 , 101 Systolic BP (mmHg) n 124 92 120 336 Mean (SD) 133.7 (17.5) 130.1 (16.9) 131.2 (10.3) 131.8 (15.2) Median 131.0 131.0 131.2 131.0 Min, Max 90 , 189 98 , 180 110 , 158 90 , 189 Sex: M / Visit: Week 16 Diastolic BP (mmHg) n 116 68 80 264 Mean (SD) 75.4 (10.7) 74.6 (8.7) 74.5 (8.8) 74.9 (9.7) Median 76.0 73.7 75.5 75.3 Min, Max 50 , 98 59 , 94 50 , 90 50 , 98 Systolic BP (mmHg) n 116 68 80 264 Mean (SD) 130.2 (18.6) 129.0 (12.5) 126.5 (12.8) 128.8 (15.6) Median 130.0 129.7 126.0 128.0 Min, Max 76 , 178 100 , 158 99 , 154 76 , 178 Sex: M / Visit: End of Treatment Diastolic BP (mmHg) n 93 69 87 249 Mean (SD) 75.1 (10.6) 74.0 (9.6) 75.6 (7.8) 75.0 (9.4) Median 73.0 74.0 76.0 74.0 Min, Max 58 , 104 52 , 94 57 , 90 52 , 104 Systolic BP (mmHg) n 93 69 87 249 Mean (SD) 128.5 (14.7) 126.8 (16.8) 127.0 (11.6) 127.5 (14.3) Median 130.0 124.0 130.0 130.0 Min, Max 78 , 164 92 , 162 100 , 156 78 , 164
# ---- Example 4: Per-page BigN — different (N=) per sex page ----
#
# Each sex page has a different per-arm population, so the `(N=x)`
# in the arm headers must vary by page. `big_n` is a wide table:
# the `by` column plus one column per arm (named as the data
# column), cells are the page-specific Ns. Each arm header then
# reads e.g. `Placebo` over `(N=53)` on the Female page and
# `(N=33)` on the Male page. RTF / PDF / DOCX carry the N on the
# repeating header; HTML and Markdown add a per-arm N row under each
# banner.
big_n <- tibble::tribble(
~sex, ~placebo, ~drug_50, ~drug_100, ~Total,
"F", 53L, 55L, 35L, 143L,
"M", 33L, 41L, 37L, 111L
)
tabular(cdisc_saf_subgroup, titles = "Vital Signs by Visit") |>
cols(
sex_n = col_spec(visible = FALSE),
paramcd = col_spec(visible = FALSE),
param = col_spec(usage = "group", label = "Parameter"),
visit = col_spec(usage = "group", label = "Visit"),
stat_label = col_spec(label = "Statistic"),
placebo = col_spec(label = "Placebo", align = "decimal"),
drug_50 = col_spec(label = "Drug 50", align = "decimal"),
drug_100 = col_spec(label = "Drug 100", align = "decimal"),
Total = col_spec(label = "Total", align = "decimal")
) |>
subgroup(by = "sex", label = "Sex: {sex}", big_n = big_n)
Vital Signs by Visit
Statistic Placebo Drug 50 Drug 100 Total Sex: F (N=53) (N=55) (N=35) (N=143) Diastolic BP (mmHg) Baseline n 208 220 140 568 Mean (SD) 77.1 (11.2) 76.3 (10.5) 78.0 (10.8) 77.0 (10.8) Median 78.0 77.3 78.3 78.0 Min, Max 40 , 110 48 , 100 51 , 108 40 , 110 Week 8 n 168 148 104 420 Mean (SD) 75.1 (9.4) 77.1 (11.0) 76.0 (10.0) 76.0 (10.1) Median 76.0 79.7 78.0 78.0 Min, Max 49 , 98 55 , 98 54 , 98 49 , 98 Week 16 n 156 100 68 324 Mean (SD) 74.9 (11.1) 75.6 (10.8) 77.8 (8.9) 75.8 (10.6) Median 77.7 76.0 79.0 78.0 Min, Max 49 , 98 55 , 98 56 , 92 49 , 98 End of Treatment n 129 108 81 318 Mean (SD) 74.0 (10.7) 77.2 (11.9) 76.5 (11.7) 75.7 (11.5) Median 74.0 79.5 80.0 78.0 Min, Max 49 , 100 50 , 100 56 , 98 49 , 100 Systolic BP (mmHg) Baseline n 208 220 140 568 Mean (SD) 141.1 (16.9) 139.2 (18.2) 140.4 (19.5) 140.2 (18.0) Median 141.8 140.0 140.0 140.0 Min, Max 100 , 184 100 , 194 100 , 192 100 , 194 Week 8 n 168 148 104 420 Mean (SD) 138.1 (16.5) 137.9 (17.8) 139.6 (19.0) 138.4 (17.6) Median 139.5 135.7 140.0 138.7 Min, Max 100 , 184 92 , 200 91 , 198 91 , 200 Week 16 n 156 100 68 324 Mean (SD) 137.9 (17.4) 134.8 (15.0) 142.0 (15.3) 137.8 (16.4) Median 139.5 130.5 140.0 138.0 Min, Max 106 , 190 100 , 168 107 , 186 100 , 190 End of Treatment n 129 108 81 318 Mean (SD) 135.8 (15.3) 137.0 (16.1) 138.0 (17.4) 136.8 (16.1) Median 133.0 133.0 140.0 136.0 Min, Max 95 , 172 98 , 178 100 , 177 95 , 178 Sex: M (N=33) (N=41) (N=37) (N=111) Diastolic BP (mmHg) Baseline n 132 164 148 444 Mean (SD) 77.1 (10.0) 77.1 (8.8) 78.5 (9.8) 77.6 (9.5) Median 76.0 76.3 80.0 76.8 Min, Max 54 , 102 58 , 108 58 , 100 54 , 108 Week 8 n 124 92 120 336 Mean (SD) 75.4 (8.8) 72.7 (9.3) 78.5 (8.1) 75.8 (9.0) Median 76.0 72.0 79.7 76.0 Min, Max 50 , 101 52 , 100 57 , 94 50 , 101 Week 16 n 116 68 80 264 Mean (SD) 75.4 (10.7) 74.6 (8.7) 74.5 (8.8) 74.9 (9.7) Median 76.0 73.7 75.5 75.3 Min, Max 50 , 98 59 , 94 50 , 90 50 , 98 End of Treatment n 93 69 87 249 Mean (SD) 75.1 (10.6) 74.0 (9.6) 75.6 (7.8) 75.0 (9.4) Median 73.0 74.0 76.0 74.0 Min, Max 58 , 104 52 , 94 57 , 90 52 , 104 Systolic BP (mmHg) Baseline n 132 164 148 444 Mean (SD) 130.0 (16.5) 136.1 (18.7) 135.3 (14.4) 134.0 (16.9) Median 130.3 134.0 137.2 132.0 Min, Max 80 , 170 100 , 188 104 , 170 80 , 188 Week 8 n 124 92 120 336 Mean (SD) 133.7 (17.5) 130.1 (16.9) 131.2 (10.3) 131.8 (15.2) Median 131.0 131.0 131.2 131.0 Min, Max 90 , 189 98 , 180 110 , 158 90 , 189 Week 16 n 116 68 80 264 Mean (SD) 130.2 (18.6) 129.0 (12.5) 126.5 (12.8) 128.8 (15.6) Median 130.0 129.7 126.0 128.0 Min, Max 76 , 178 100 , 158 99 , 154 76 , 178 End of Treatment n 93 69 87 249 Mean (SD) 128.5 (14.7) 126.8 (16.8) 127.0 (11.6) 127.5 (14.3) Median 130.0 124.0 130.0 130.0 Min, Max 78 , 164 92 , 162 100 , 156 78 , 164
# ---- Example 5: Clear a partition with subgroup(character()) ----
#
# `subgroup(by = character())` (or `subgroup(by = NULL)`) explicitly
# clears any prior partition — useful in programmatically-built
# pipelines where a downstream branch decides not to paginate by
# group after all. Give `sex` a `usage = "group"` role up front:
# while the sex partition is active it overrides that role (sex
# becomes the per-page banner); once cleared, sex falls back to a
# group level, so the pooled single-page render nests sex, parameter,
# and visit rather than leaving a stray partition column behind.
tabular(cdisc_saf_subgroup, titles = "Pooled (no sex partition)") |>
cols(
sex_n = col_spec(visible = FALSE),
paramcd = col_spec(visible = FALSE),
sex = col_spec(usage = "group", label = "Sex"),
param = col_spec(usage = "group", label = "Parameter"),
visit = col_spec(usage = "group", label = "Visit"),
stat_label = col_spec(label = "Statistic"),
placebo = col_spec(label = "Placebo", align = "decimal"),
drug_50 = col_spec(label = "Drug 50", align = "decimal"),
drug_100 = col_spec(label = "Drug 100", align = "decimal"),
Total = col_spec(label = "Total", align = "decimal")
) |>
subgroup("sex", label = "Sex: {sex}") |>
# Decide later that the sex split was the wrong default —
# clear it before rendering.
subgroup(character())
Pooled (no sex partition)
Statistic Placebo Drug 50 Drug 100 Total F Diastolic BP (mmHg) Baseline n 208 220 140 568 Mean (SD) 77.1 (11.2) 76.3 (10.5) 78.0 (10.8) 77.0 (10.8) Median 78.0 77.3 78.3 78.0 Min, Max 40 , 110 48 , 100 51 , 108 40 , 110 Week 8 n 168 148 104 420 Mean (SD) 75.1 (9.4) 77.1 (11.0) 76.0 (10.0) 76.0 (10.1) Median 76.0 79.7 78.0 78.0 Min, Max 49 , 98 55 , 98 54 , 98 49 , 98 Week 16 n 156 100 68 324 Mean (SD) 74.9 (11.1) 75.6 (10.8) 77.8 (8.9) 75.8 (10.6) Median 77.7 76.0 79.0 78.0 Min, Max 49 , 98 55 , 98 56 , 92 49 , 98 End of Treatment n 129 108 81 318 Mean (SD) 74.0 (10.7) 77.2 (11.9) 76.5 (11.7) 75.7 (11.5) Median 74.0 79.5 80.0 78.0 Min, Max 49 , 100 50 , 100 56 , 98 49 , 100 Systolic BP (mmHg) Baseline n 208 220 140 568 Mean (SD) 141.1 (16.9) 139.2 (18.2) 140.4 (19.5) 140.2 (18.0) Median 141.8 140.0 140.0 140.0 Min, Max 100 , 184 100 , 194 100 , 192 100 , 194 Week 8 n 168 148 104 420 Mean (SD) 138.1 (16.5) 137.9 (17.8) 139.6 (19.0) 138.4 (17.6) Median 139.5 135.7 140.0 138.7 Min, Max 100 , 184 92 , 200 91 , 198 91 , 200 Week 16 n 156 100 68 324 Mean (SD) 137.9 (17.4) 134.8 (15.0) 142.0 (15.3) 137.8 (16.4) Median 139.5 130.5 140.0 138.0 Min, Max 106 , 190 100 , 168 107 , 186 100 , 190 End of Treatment n 129 108 81 318 Mean (SD) 135.8 (15.3) 137.0 (16.1) 138.0 (17.4) 136.8 (16.1) Median 133.0 133.0 140.0 136.0 Min, Max 95 , 172 98 , 178 100 , 177 95 , 178 M Diastolic BP (mmHg) Baseline n 132 164 148 444 Mean (SD) 77.1 (10.0) 77.1 (8.8) 78.5 (9.8) 77.6 (9.5) Median 76.0 76.3 80.0 76.8 Min, Max 54 , 102 58 , 108 58 , 100 54 , 108 Week 8 n 124 92 120 336 Mean (SD) 75.4 (8.8) 72.7 (9.3) 78.5 (8.1) 75.8 (9.0) Median 76.0 72.0 79.7 76.0 Min, Max 50 , 101 52 , 100 57 , 94 50 , 101 Week 16 n 116 68 80 264 Mean (SD) 75.4 (10.7) 74.6 (8.7) 74.5 (8.8) 74.9 (9.7) Median 76.0 73.7 75.5 75.3 Min, Max 50 , 98 59 , 94 50 , 90 50 , 98 End of Treatment n 93 69 87 249 Mean (SD) 75.1 (10.6) 74.0 (9.6) 75.6 (7.8) 75.0 (9.4) Median 73.0 74.0 76.0 74.0 Min, Max 58 , 104 52 , 94 57 , 90 52 , 104 Systolic BP (mmHg) Baseline n 132 164 148 444 Mean (SD) 130.0 (16.5) 136.1 (18.7) 135.3 (14.4) 134.0 (16.9) Median 130.3 134.0 137.2 132.0 Min, Max 80 , 170 100 , 188 104 , 170 80 , 188 Week 8 n 124 92 120 336 Mean (SD) 133.7 (17.5) 130.1 (16.9) 131.2 (10.3) 131.8 (15.2) Median 131.0 131.0 131.2 131.0 Min, Max 90 , 189 98 , 180 110 , 158 90 , 189 Week 16 n 116 68 80 264 Mean (SD) 130.2 (18.6) 129.0 (12.5) 126.5 (12.8) 128.8 (15.6) Median 130.0 129.7 126.0 128.0 Min, Max 76 , 178 100 , 158 99 , 154 76 , 178 End of Treatment n 93 69 87 249 Mean (SD) 128.5 (14.7) 126.8 (16.8) 127.0 (11.6) 127.5 (14.3) Median 130.0 124.0 130.0 130.0 Min, Max 78 , 164 92 , 162 100 , 156 78 , 164