I am trying to create table shell below. First row is event level count, 2nd and onwards are subject level.
I have tried following code.
# Read in data
adsl <- cards::ADSL %>%
mutate(TRTA = TRT01A)
adcm <- pharmaverseadam::adcm %>%
filter(SAFFL == "Y" & ONTRTFL == 'Y') %>%
select(c(USUBJID, TRTA, CMTRT, CMCLAS, CMDECOD, ONTRTFL))
# Event level counts
tbl1 <- adcm %>% tbl_hierarchical_count(
by = TRTA,
variables = c(CMTRT),
overall_row = TRUE,
label = list(..ard_hierarchical_overall.. = "TOTAL NUMBER OF CONCOMITANT MEDICATIONS")
) %>% add_overall(last = TRUE)
tbl1$table_body <- tbl1$table_body %>%
filter(grepl("ard_hierarchical", variable))
# Subject level counts
tbl2 <- adcm %>% tbl_hierarchical(
by = c(TRTA),
variables = c(CMCLAS, CMDECOD),
denominator = adsl,
id = USUBJID,
include = everything(),
statistic = everything() ~ "{n} ({p}%)",
overall_row = TRUE,
label = list(
..ard_hierarchical_overall.. = "NUMBER OF PARTICIPANTS WITH ANY CONCOMITANT MEDICATION")
) %>%
add_overall(last = TRUE)
# Stack the tables together
tbl.final <- tbl_stack(list(tbl1, tbl2),
quiet = TRUE) %>%
# Modify the zero percent
modify_table_body(
~ .x %>%
dplyr::mutate(across(
all_stat_cols(), ~ dplyr::case_when(. == "0.0 (0.00)" ~ "0", TRUE ~ .)
))) %>%
# Update header
modify_header(
all_stat_cols() ~ "**{level}** \n(N = {n}) <br>n(%)",
label ~ "**ATC Level 4 <br> Preferred Term**") %>%
# Remove default footnote
remove_footnote_header(columns = all_stat_cols()) %>%
# Create GT for print
as_gt()
tbl.final$`_data` <- tbl.final$`_data` %>%
mutate(tbl_id1 = if_else(!grepl("ard_hierarchical", variable),3,tbl_id1))
# Add blank rows for each tbl_id1
tbl.final <- tbl.final %>%
gt::tab_row_group(
label = md("<br>"),
rows = tbl_id1 <= 1
) %>%
tab_options(row_group.default_label = md("<br>"))
Facing couple of issues here.
tbl2
have header N counts; but after stacking tbl.final
loses the information. (N = NA) in output.tab_row_group
(yellow highlights below). I tried using the tbl_id
information. However, it didn't work as expected.
Final output I have is below.
Can someone please help me figure this out? Thank you!!
I would create this table by first creating a table with the first row only using tbl_summary()
. Then I would create the rest of the table with tbl_hierarchical()
. Lastly, I would stack them with tbl_stack()
.
In the example below, I used ADAE instead of con meds, but they idea is the same.
library(gtsummary)
packageVersion("gtsummary")
#> [1] '2.1.0'
tbl_row_one <-
# merge in the number of AEs into ADSL
cards::ADSL |>
dplyr::left_join(
cards::ADAE |>
dplyr::summarise(.by = USUBJID, AE_COUNT = length(USUBJID)),
by = "USUBJID"
) |>
dplyr::rename(TRTA = ARM) |>
tbl_summary(
by = TRTA,
include = AE_COUNT,
statistic = AE_COUNT ~ "{sum}",
digits = AE_COUNT ~ 0,
label = list(AE_COUNT = "TOTAL NUMBER OF AEs"),
missing = "no"
) |>
add_overall(last = TRUE) |>
remove_footnote_header(columns = everything())
tbl_ae <-
cards::ADAE |>
tbl_hierarchical(
by = TRTA,
variables = c(AESOC, AEDECOD),
include = AEDECOD,
id = USUBJID,
denominator = cards::ADSL |> dplyr::rename(TRTA = ARM),
overall_row = TRUE,
label = list(..ard_hierarchical_overall.. = "NUMBER OF SUBJECTS WITH AT LEAST ONE AE")
) |>
add_overall(last = TRUE)
# combine the tables
tbl_final <-
list(tbl_row_one, tbl_ae) |>
tbl_stack() |>
modify_header(label = "**Primary System Organ Class** \n\U00A0\U00A0\U00A0\U00A0**Dictionary-Derived Term**") |>
# insert blank rows
modify_table_body(
~ .x |>
dplyr::add_row(data.frame(label = NA), .after = 2L) |>
dplyr::add_row(data.frame(label = NA), .after = 1L)
)
#> Column headers among stacked tables differ. Headers from the first table are
#> used.
#> ℹ Check the header is correct and use `modify_header()` to update, or `quiet =
#> TRUE` to suppress this message.
Created on 2025-04-07 with reprex v2.1.1