gtsummary merge checks

Setup

pak::pak("ddsjoberg/gtsummary@1861-tbl_merge-vars")

library(tidyverse)
library(gtsummary)
library(survival)
library(labelled)
packageVersion("gtsummary")
[1] '2.0.4.9009'
theme_gtsummary_compact()

temp_lib_loc <- fs::path_temp("lib")
temp_lib_loc
/var/folders/6f/gdjf_vxj2wl3jhmxdkd1hd_w0000gn/T/RtmplMLlxJ/lib
dir.create(temp_lib_loc)

# install the old version of gtsummary into the temp lib
pak::pak("broom.helpers@1.15.0", lib = temp_lib_loc)
pak::pak("gtsummary@1.7.2", lib = temp_lib_loc)

trial2 <- trial %>%
  mutate(age2 = age)

var_label(trial2$age) <- "Age 2"
var_label(trial2$age2) <- "Age"

ex1 - from help doc

t1 <-
  glm(response ~ trt + grade + age, trial, family = binomial) %>%
  tbl_regression(exponentiate = TRUE)
t2 <-
  coxph(Surv(ttdeath, death) ~ trt + grade + age, trial) %>%
  tbl_regression(exponentiate = TRUE)

tbl_merge(
  tbls = list(t1, t2),
  tab_spanner = c("**Tumor Response**", "**Time to Death**")
) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(
      tbls = list(t1, t2),
      tab_spanner = c("**Tumor Response**", "**Time to Death**")
    ) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio

when variable and labels are the same can merge just by row_type and label

tbl_merge(
  tbls = list(t1, t2),
  tab_spanner = c("**Tumor Response**", "**Time to Death**"),
  merge_vars = c( "row_type","label")) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(
      tbls = list(t1, t2),
      tab_spanner = c("**Tumor Response**", "**Time to Death**"),
      merge_vars = c( "row_type","label")) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio

ex2 change label and keep variable name the same

t3 <-
  coxph(Surv(ttdeath, death) ~ trt + grade + age, trial2) %>%
  tbl_regression(exponentiate = TRUE)

# two rows for age here
tbl_merge(
  tbls = list(t1, t3),
  tab_spanner = c("**Tumor Response**", "**Time to Death**")
) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10


Age 2


1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(
      tbls = list(t1, t2),
      tab_spanner = c("**Tumor Response**", "**Time to Death**"),
      merge_vars = c( "row_type","label")) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio

two rows for age here as well as the second characteristic column is kept and the merge duplicates rows for each variable. Error message does say this will happen.

tbl_merge(
  tbls = list(t1, t3),
  tab_spanner = c("**Tumor Response**", "**Time to Death**"),
  merge_vars = c("variable", "row_type", "var_label")) |> 
  modify_caption("NEW MERGE")
The merging columns ("variable", "row_type", and "var_label") do not uniquely
identify rows for each table in `tbls`, and the merge may fail or result in a
malformed table.
ℹ If you previously called `tbl_stack()` on your tables, then merging with
  `tbl_merge()` before calling `tbl_stack` may resolve the issue.
NEW MERGE
Tumor Response
Time to Death
Characteristic OR 95% CI p-value Characteristic HR 95% CI p-value
Chemotherapy Treatment


Chemotherapy Treatment


    Drug A
    Drug A
    Drug A
    Drug B 1.30 0.88, 1.92 0.2
    Drug B 1.13 0.60, 2.13 0.7     Drug A
    Drug B 1.13 0.60, 2.13 0.7     Drug B 1.30 0.88, 1.92 0.2
Grade


Grade


    I
    I
    I
    II 1.21 0.73, 1.99 0.5
    I
    III 1.79 1.12, 2.86 0.014
    II 0.85 0.39, 1.85 0.7     I
    II 0.85 0.39, 1.85 0.7     II 1.21 0.73, 1.99 0.5
    II 0.85 0.39, 1.85 0.7     III 1.79 1.12, 2.86 0.014
    III 1.01 0.47, 2.15 >0.9     I
    III 1.01 0.47, 2.15 >0.9     II 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9     III 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10







Age 2 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(
      tbls = list(t1, t3),
      tab_spanner = c("**Tumor Response**", "**Time to Death**"),
      merge_vars = c("variable", "row_type", "var_label")) |> 
    modify_caption("OLD MERGE")
)
The merging columns ("variable", "row_type", and "var_label") do not uniquely
identify rows for each table in `tbls`, and the merge may fail or result in a
malformed table.
ℹ If you previously called `tbl_stack()` on your tables, then merging with
  `tbl_merge()` before calling `tbl_stack` may resolve the issue.
OLD MERGE
Tumor Response
Time to Death
Characteristic OR 95% CI p-value Characteristic HR 95% CI p-value
Chemotherapy Treatment


Chemotherapy Treatment


    Drug A
    Drug A
    Drug A
    Drug B 1.30 0.88, 1.92 0.2
    Drug B 1.13 0.60, 2.13 0.7     Drug A
    Drug B 1.13 0.60, 2.13 0.7     Drug B 1.30 0.88, 1.92 0.2
Grade


Grade


    I
    I
    I
    II 1.21 0.73, 1.99 0.5
    I
    III 1.79 1.12, 2.86 0.014
    II 0.85 0.39, 1.85 0.7     I
    II 0.85 0.39, 1.85 0.7     II 1.21 0.73, 1.99 0.5
    II 0.85 0.39, 1.85 0.7     III 1.79 1.12, 2.86 0.014
    III 1.01 0.47, 2.15 >0.9     I
    III 1.01 0.47, 2.15 >0.9     II 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9     III 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10







Age 2 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio

One row for age here, the second characteristic column is kept and the merge duplicates rows for each variable. Error message does say this will happen.

tbl_merge(
  tbls = list(t1, t3),
  tab_spanner = c("**Tumor Response**", "**Time to Death**"),
  merge_vars = c("variable", "row_type")) |> 
  modify_caption("NEW MERGE")
The merging columns ("variable" and "row_type") do not uniquely identify rows
for each table in `tbls`, and the merge may fail or result in a malformed
table.
ℹ If you previously called `tbl_stack()` on your tables, then merging with
  `tbl_merge()` before calling `tbl_stack` may resolve the issue.
NEW MERGE
Tumor Response
Time to Death
Characteristic OR 95% CI p-value Characteristic HR 95% CI p-value
Chemotherapy Treatment


Chemotherapy Treatment


    Drug A
    Drug A
    Drug A
    Drug B 1.30 0.88, 1.92 0.2
    Drug B 1.13 0.60, 2.13 0.7     Drug A
    Drug B 1.13 0.60, 2.13 0.7     Drug B 1.30 0.88, 1.92 0.2
Grade


Grade


    I
    I
    I
    II 1.21 0.73, 1.99 0.5
    I
    III 1.79 1.12, 2.86 0.014
    II 0.85 0.39, 1.85 0.7     I
    II 0.85 0.39, 1.85 0.7     II 1.21 0.73, 1.99 0.5
    II 0.85 0.39, 1.85 0.7     III 1.79 1.12, 2.86 0.014
    III 1.01 0.47, 2.15 >0.9     I
    III 1.01 0.47, 2.15 >0.9     II 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9     III 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10 Age 2 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(
      tbls = list(t1, t3),
      tab_spanner = c("**Tumor Response**", "**Time to Death**"),
      merge_vars = c("variable", "row_type")) |> 
    modify_caption("OLD MERGE")
)
The merging columns ("variable" and "row_type") do not uniquely identify rows
for each table in `tbls`, and the merge may fail or result in a malformed
table.
ℹ If you previously called `tbl_stack()` on your tables, then merging with
  `tbl_merge()` before calling `tbl_stack` may resolve the issue.
OLD MERGE
Tumor Response
Time to Death
Characteristic OR 95% CI p-value Characteristic HR 95% CI p-value
Chemotherapy Treatment


Chemotherapy Treatment


    Drug A
    Drug A
    Drug A
    Drug B 1.30 0.88, 1.92 0.2
    Drug B 1.13 0.60, 2.13 0.7     Drug A
    Drug B 1.13 0.60, 2.13 0.7     Drug B 1.30 0.88, 1.92 0.2
Grade


Grade


    I
    I
    I
    II 1.21 0.73, 1.99 0.5
    I
    III 1.79 1.12, 2.86 0.014
    II 0.85 0.39, 1.85 0.7     I
    II 0.85 0.39, 1.85 0.7     II 1.21 0.73, 1.99 0.5
    II 0.85 0.39, 1.85 0.7     III 1.79 1.12, 2.86 0.014
    III 1.01 0.47, 2.15 >0.9     I
    III 1.01 0.47, 2.15 >0.9     II 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9     III 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10 Age 2 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio

ex3 change variable name and keep label the same

table does not merge properly because of mismatch between labels and variables but no error is thrown

t4 <-
  coxph(Surv(ttdeath, death) ~ trt + grade + age2, trial2) %>%
  tbl_regression(exponentiate = TRUE)

tbl_merge(
  tbls = list(t1, t4),
  tab_spanner = c("**Tumor Response**", "**Time to Death**")
) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10


Age


1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(
      tbls = list(t1, t4),
      tab_spanner = c("**Tumor Response**", "**Time to Death**")
    ) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10


Age


1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio

we can use the following

tbl_merge(
  tbls = list(t1, t4),
  tab_spanner = c("**Tumor Response**", "**Time to Death**"),
  merge_vars = c( "row_type", "label")) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(
      tbls = list(t1, t4),
      tab_spanner = c("**Tumor Response**", "**Time to Death**"),
      merge_vars = c( "row_type", "label")) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Tumor Response
Time to Death
OR 95% CI p-value HR 95% CI p-value
Chemotherapy Treatment





    Drug A

    Drug B 1.13 0.60, 2.13 0.7 1.30 0.88, 1.92 0.2
Grade





    I

    II 0.85 0.39, 1.85 0.7 1.21 0.73, 1.99 0.5
    III 1.01 0.47, 2.15 >0.9 1.79 1.12, 2.86 0.014
Age 1.02 1.00, 1.04 0.10 1.01 0.99, 1.02 0.3
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio

ex4 stack and merge

t1s <- tbl_stack(list(tbl_summary(trial, by = trt, include = age),
                      tbl_summary(trial, by = trt, include = grade)))

t2s <- tbl_stack(list(tbl_summary(trial, by = trt, include = age),
                      tbl_summary(trial, by = trt, include = grade)))


tbl_merge(list(t1s, t2s),
          merge_vars = c("row_type", "label")) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Table 1
Table 2
Drug A
N = 981
Drug B
N = 1021
Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56) 46 (37, 60) 48 (39, 56)
    Unknown 7 4 7 4
Grade



    I 35 (36%) 33 (32%) 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%) 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%) 31 (32%) 33 (32%)
1 Median (Q1, Q3)
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(list(t1s, t2s),
              merge_vars = c("row_type", "label")) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Table 1
Table 2
Drug A
N = 981
Drug B
N = 1021
Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56) 46 (37, 60) 48 (39, 56)
    Unknown 7 4 7 4
Grade



    I 35 (36%) 33 (32%) 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%) 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%) 31 (32%) 33 (32%)
1 Median (Q1, Q3)

ex5 stack and merge same variable different label

t3s <- tbl_stack(list(tbl_summary(trial2, by = trt, include = age),
                      tbl_summary(trial2, by = trt, include = grade)))

#same results at ex2 above
tbl_merge(list(t1s, t3s),
          merge_vars = c("variable", "row_type")) |> 
  modify_caption("NEW MERGE")
The merging columns ("variable" and "row_type") do not uniquely identify rows
for each table in `tbls`, and the merge may fail or result in a malformed
table.
ℹ If you previously called `tbl_stack()` on your tables, then merging with
  `tbl_merge()` before calling `tbl_stack` may resolve the issue.
NEW MERGE
Table 1
Table 2
Characteristic Drug A
N = 981
Drug B
N = 1021
Characteristic Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56) Age 2 46 (37, 60) 48 (39, 56)
    Unknown 7 4     Unknown 7 4
Grade

Grade

    I 35 (36%) 33 (32%)     I 35 (36%) 33 (32%)
    I 35 (36%) 33 (32%)     II 32 (33%) 36 (35%)
    I 35 (36%) 33 (32%)     III 31 (32%) 33 (32%)
    II 32 (33%) 36 (35%)     I 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%)     II 32 (33%) 36 (35%)
    II 32 (33%) 36 (35%)     III 31 (32%) 33 (32%)
    III 31 (32%) 33 (32%)     I 35 (36%) 33 (32%)
    III 31 (32%) 33 (32%)     II 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%)     III 31 (32%) 33 (32%)
1 Median (Q1, Q3)
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(list(t1s, t3s),
              merge_vars = c("variable", "row_type")) |> 
    modify_caption("OLD MERGE")
)
The merging columns ("variable" and "row_type") do not uniquely identify rows
for each table in `tbls`, and the merge may fail or result in a malformed
table.
ℹ If you previously called `tbl_stack()` on your tables, then merging with
  `tbl_merge()` before calling `tbl_stack` may resolve the issue.
OLD MERGE
Table 1
Table 2
Characteristic Drug A
N = 981
Drug B
N = 1021
Characteristic Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56) Age 2 46 (37, 60) 48 (39, 56)
    Unknown 7 4     Unknown 7 4
Grade

Grade

    I 35 (36%) 33 (32%)     I 35 (36%) 33 (32%)
    I 35 (36%) 33 (32%)     II 32 (33%) 36 (35%)
    I 35 (36%) 33 (32%)     III 31 (32%) 33 (32%)
    II 32 (33%) 36 (35%)     I 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%)     II 32 (33%) 36 (35%)
    II 32 (33%) 36 (35%)     III 31 (32%) 33 (32%)
    III 31 (32%) 33 (32%)     I 35 (36%) 33 (32%)
    III 31 (32%) 33 (32%)     II 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%)     III 31 (32%) 33 (32%)
1 Median (Q1, Q3)

we can use….

tbl_merge(list(t1s, t3s),
          merge_vars = c("variable", "row_type", "var_label")) |> 
  modify_caption("NEW MERGE")
The merging columns ("variable", "row_type", and "var_label") do not uniquely
identify rows for each table in `tbls`, and the merge may fail or result in a
malformed table.
ℹ If you previously called `tbl_stack()` on your tables, then merging with
  `tbl_merge()` before calling `tbl_stack` may resolve the issue.
NEW MERGE
Table 1
Table 2
Characteristic Drug A
N = 981
Drug B
N = 1021
Characteristic Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56)


    Unknown 7 4


Grade

Grade

    I 35 (36%) 33 (32%)     I 35 (36%) 33 (32%)
    I 35 (36%) 33 (32%)     II 32 (33%) 36 (35%)
    I 35 (36%) 33 (32%)     III 31 (32%) 33 (32%)
    II 32 (33%) 36 (35%)     I 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%)     II 32 (33%) 36 (35%)
    II 32 (33%) 36 (35%)     III 31 (32%) 33 (32%)
    III 31 (32%) 33 (32%)     I 35 (36%) 33 (32%)
    III 31 (32%) 33 (32%)     II 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%)     III 31 (32%) 33 (32%)



Age 2 46 (37, 60) 48 (39, 56)



    Unknown 7 4
1 Median (Q1, Q3)
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(list(t1s, t3s),
              merge_vars = c("variable", "row_type", "var_label")) |> 
    modify_caption("OLD MERGE")
)
The merging columns ("variable", "row_type", and "var_label") do not uniquely
identify rows for each table in `tbls`, and the merge may fail or result in a
malformed table.
ℹ If you previously called `tbl_stack()` on your tables, then merging with
  `tbl_merge()` before calling `tbl_stack` may resolve the issue.
OLD MERGE
Table 1
Table 2
Characteristic Drug A
N = 981
Drug B
N = 1021
Characteristic Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56)


    Unknown 7 4


Grade

Grade

    I 35 (36%) 33 (32%)     I 35 (36%) 33 (32%)
    I 35 (36%) 33 (32%)     II 32 (33%) 36 (35%)
    I 35 (36%) 33 (32%)     III 31 (32%) 33 (32%)
    II 32 (33%) 36 (35%)     I 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%)     II 32 (33%) 36 (35%)
    II 32 (33%) 36 (35%)     III 31 (32%) 33 (32%)
    III 31 (32%) 33 (32%)     I 35 (36%) 33 (32%)
    III 31 (32%) 33 (32%)     II 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%)     III 31 (32%) 33 (32%)



Age 2 46 (37, 60) 48 (39, 56)



    Unknown 7 4
1 Median (Q1, Q3)

ex 6 stack and merge, different variable same label

t4s <- tbl_stack(list(tbl_summary(trial2, by = trt, include = age2),
                      tbl_summary(trial2, by = trt, include = grade)))

# does merge, shows two age variables
tbl_merge(
  tbls = list(t1s, t4s)) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Table 1
Table 2
Drug A
N = 981
Drug B
N = 1021
Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56)

    Unknown 7 4

Grade



    I 35 (36%) 33 (32%) 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%) 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%) 31 (32%) 33 (32%)
Age

46 (37, 60) 48 (39, 56)
    Unknown

7 4
1 Median (Q1, Q3)
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(
      tbls = list(t1s, t4s)) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Table 1
Table 2
Drug A
N = 981
Drug B
N = 1021
Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56)

    Unknown 7 4

Grade



    I 35 (36%) 33 (32%) 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%) 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%) 31 (32%) 33 (32%)
Age

46 (37, 60) 48 (39, 56)
    Unknown

7 4
1 Median (Q1, Q3)

can use

tbl_merge(
  tbls = list(t1s, t4s),
  merge_vars = c( "row_type", "label")) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Table 1
Table 2
Drug A
N = 981
Drug B
N = 1021
Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56) 46 (37, 60) 48 (39, 56)
    Unknown 7 4 7 4
Grade



    I 35 (36%) 33 (32%) 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%) 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%) 31 (32%) 33 (32%)
1 Median (Q1, Q3)
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(
      tbls = list(t1s, t4s),
      merge_vars = c( "row_type", "label")) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Table 1
Table 2
Drug A
N = 981
Drug B
N = 1021
Drug A
N = 981
Drug B
N = 1021
Age 46 (37, 60) 48 (39, 56) 46 (37, 60) 48 (39, 56)
    Unknown 7 4 7 4
Grade



    I 35 (36%) 33 (32%) 35 (36%) 33 (32%)
    II 32 (33%) 36 (35%) 32 (33%) 36 (35%)
    III 31 (32%) 33 (32%) 31 (32%) 33 (32%)
1 Median (Q1, Q3)

ex7 stack and merge different levels included

t1sm <- tbl_stack(list(tbl_summary(trial %>% filter(grade %in% c("I","II")), by = trt, include = age),
                       tbl_summary(trial %>% filter(grade %in% c("I","II")),
                                   by = trt, include = grade)))

t2sm <- tbl_stack(list(tbl_summary(trial %>% filter(grade %in% c("II","III")), by = trt, include = age),
                       tbl_summary(trial %>% filter(grade %in% c("II","III")), by = trt, include = grade)))



tbl_merge(list(t1sm, t2sm)) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Table 1
Table 2
Drug A
N = 671
Drug B
N = 691
Drug A
N = 631
Drug B
N = 691
Age 45 (34, 56) 49 (42, 57) 47 (38, 58) 49 (38, 57)
    Unknown 4 4 5 4
Grade



    I 35 (52%) 33 (48%) 0 (0%) 0 (0%)
    II 32 (48%) 36 (52%) 32 (51%) 36 (52%)
    III 0 (0%) 0 (0%) 31 (49%) 33 (48%)
1 Median (Q1, Q3)
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(list(t1sm, t2sm)) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Table 1
Table 2
Drug A
N = 671
Drug B
N = 691
Drug A
N = 631
Drug B
N = 691
Age 45 (34, 56) 49 (42, 57) 47 (38, 58) 49 (38, 57)
    Unknown 4 4 5 4
Grade



    I 35 (52%) 33 (48%) 0 (0%) 0 (0%)
    II 32 (48%) 36 (52%) 32 (51%) 36 (52%)
    III 0 (0%) 0 (0%) 31 (49%) 33 (48%)
1 Median (Q1, Q3)

ex8 change variable to charcater keep label the same

trial3 <- trial %>%
  mutate(grade = as.character(grade))

var_label(trial3$grade) <- "Grade"

t3sm <- tbl_stack(list(tbl_summary(trial3 %>% filter(grade %in% c("II","III")), by = trt, include = age),
                       tbl_summary(trial3 %>% filter(grade %in% c("II","III")), by = trt, include = grade)))
#merges as expected even when one was factor and other was character
tbl_merge(list(t1sm, t3sm)) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Table 1
Table 2
Drug A
N = 671
Drug B
N = 691
Drug A
N = 631
Drug B
N = 691
Age 45 (34, 56) 49 (42, 57) 47 (38, 58) 49 (38, 57)
    Unknown 4 4 5 4
Grade



    I 35 (52%) 33 (48%)

    II 32 (48%) 36 (52%) 32 (51%) 36 (52%)
    III 0 (0%) 0 (0%) 31 (49%) 33 (48%)
1 Median (Q1, Q3)
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(list(t1sm, t3sm)) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Table 1
Table 2
Drug A
N = 671
Drug B
N = 691
Drug A
N = 631
Drug B
N = 691
Age 45 (34, 56) 49 (42, 57) 47 (38, 58) 49 (38, 57)
    Unknown 4 4 5 4
Grade



    I 35 (52%) 33 (48%)

    II 32 (48%) 36 (52%) 32 (51%) 36 (52%)
    III 0 (0%) 0 (0%) 31 (49%) 33 (48%)
1 Median (Q1, Q3)

ex9 change label, stack and merge, different variable levels

var_label(trial3$grade) <- "Grade2"

t5sm <- tbl_stack(list(tbl_summary(trial3 %>% filter(grade %in% c("II","III")), by = trt, include = age),
                       tbl_summary(trial3 %>% filter(grade %in% c("II","III")), by = trt, include = grade)))

# two grade variables appear as expected
tbl_merge(list(t1sm, t5sm)) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Table 1
Table 2
Drug A
N = 671
Drug B
N = 691
Drug A
N = 631
Drug B
N = 691
Age 45 (34, 56) 49 (42, 57) 47 (38, 58) 49 (38, 57)
    Unknown 4 4 5 4
Grade



    I 35 (52%) 33 (48%)

    II 32 (48%) 36 (52%)

    III 0 (0%) 0 (0%)

Grade2



    II

32 (51%) 36 (52%)
    III

31 (49%) 33 (48%)
1 Median (Q1, Q3)
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(list(t1sm, t5sm)) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Table 1
Table 2
Drug A
N = 671
Drug B
N = 691
Drug A
N = 631
Drug B
N = 691
Age 45 (34, 56) 49 (42, 57) 47 (38, 58) 49 (38, 57)
    Unknown 4 4 5 4
Grade



    I 35 (52%) 33 (48%)

    II 32 (48%) 36 (52%)

    III 0 (0%) 0 (0%)

Grade2



    II

32 (51%) 36 (52%)
    III

31 (49%) 33 (48%)
1 Median (Q1, Q3)

no error thrown but grade 2 appears at bottom of table with no variable information

tbl_merge(list(t1sm, t5sm),
          merge_vars = c("variable","row_type","label")) |> 
  modify_caption("NEW MERGE")
NEW MERGE
Characteristic
Table 1
Table 2
Drug A
N = 671
Drug B
N = 691
Drug A
N = 631
Drug B
N = 691
Age 45 (34, 56) 49 (42, 57) 47 (38, 58) 49 (38, 57)
    Unknown 4 4 5 4
Grade



    I 35 (52%) 33 (48%)

    II 32 (48%) 36 (52%) 32 (51%) 36 (52%)
    III 0 (0%) 0 (0%) 31 (49%) 33 (48%)
Grade2



1 Median (Q1, Q3)
withr::with_package(
  package = "gtsummary",
  lib.loc = temp_lib_loc,
  code = 
    tbl_merge(list(t1sm, t5sm),
              merge_vars = c("variable","row_type","label")) |> 
    modify_caption("OLD MERGE")
)
OLD MERGE
Characteristic
Table 1
Table 2
Drug A
N = 671
Drug B
N = 691
Drug A
N = 631
Drug B
N = 691
Age 45 (34, 56) 49 (42, 57) 47 (38, 58) 49 (38, 57)
    Unknown 4 4 5 4
Grade



    I 35 (52%) 33 (48%)

    II 32 (48%) 36 (52%) 32 (51%) 36 (52%)
    III 0 (0%) 0 (0%) 31 (49%) 33 (48%)
Grade2



1 Median (Q1, Q3)