Skip to content

Bug Report: span_structure with repeated mid-level labels groups columns incorrectly #637

Description

@sevakkam-hub

What happened?

Description

When using col_plan with span_structure across three column levels, mid-level labels that repeat
across top-level groups (e.g. "Female" under both "Active" and "Placebo") get merged into a
single spanner. The columns are reordered so that all "Female" leaf columns are grouped together
under one span, and all "Male" leaf columns under another — breaking the intended treatment-first
hierarchy.

Reproducible example

library(tfrmt)
library(tibble)

ard <- tribble(
~row_label, ~trt, ~sex_trt, ~stat, ~param, ~value,
"Subjects", "Active", "Active_Female", "n", "val", 40,
"Subjects", "Active", "Active_Female", "pct", "val", 47.1,
"Subjects", "Active", "Active_Male", "n", "val", 45,
"Subjects", "Active", "Active_Male", "pct", "val", 52.9,
"Subjects", "Placebo", "Placebo_Female", "n", "val", 38,
"Subjects", "Placebo", "Placebo_Female", "pct", "val", 50.7,
"Subjects", "Placebo", "Placebo_Male", "n", "val", 37,
"Subjects", "Placebo", "Placebo_Male", "pct", "val", 49.3,
)

freq_tfrmt <- tfrmt(
label = "row_label",
column = c(trt, sex_trt, stat),
param = "param",
value = "value",
body_plan = body_plan(
frmt_structure(group_val = ".default", label_val = ".default", val = frmt("xx.x"))
),
col_plan = col_plan(
span_structure(
trt = "Active",
sex_trt = c("Female" = "Active_Female", "Male" = "Active_Male"),
stat = c(n, pct)
),
span_structure(
trt = "Placebo",
sex_trt = c("Female" = "Placebo_Female", "Male" = "Placebo_Male"),
stat = c(n, pct)
)
)
)

print_to_gt(freq_tfrmt, .data = ard)

Expected
| Active | Placebo | Active | Placebo |
| Female | Male | Female | Male |
| n | pct | n | pct | n | pct | n | pct |

Actual
| Active | Placebo | Active | Placebo |
| Female | Male |
| n | pct | n | pct | n | pct | n | pct |

Root cause

In format_gt_column_labels (R/print_to_gt.R), the code uses group_by(.data$value) which groups by
label alone, ignoring parent context. All "Female" rows — regardless of whether they belong to
"Active" or "Placebo" — are merged into one spanner, reordering columns in the process.

Proposed fix

Group by the full ancestral path rather than label alone, and pass an explicit level to
tab_spanner:

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions