I want to generate the Study Completion Status in the ds table like this:
Study Completion Status in the ds table

However, when EOSSTT == "COMPLETED" or "ONGOING", the value of DCSREAS will be NA. So when I use tbl_hierarchical to generate the table, only the EOSSTT == "DISCONTINUED" part remains
adsl <- random.cdisc.data::cadsl
tbl_study <- gtsummary::tbl_hierarchical(
data = adsl,
denominator = adsl,
id = USUBJID,
by = TRT01P,
variables = c("EOSSTT", "DCSREAS"))

Is there a way to make the parts where EOSSTT == "COMPLETED" or "ONGOING" also show up, like in the below image?

I would use tbl_summary() for this one, as it's just the tabulation of 2 variables. The hierarchical tables are suited for highly nested structures (e.g. AEs within SOC). While the final presentation looks nested, we can also look at it as simple indentation for the reason variable.
library(gtsummary)
adsl <-
random.cdisc.data::cadsl |>
# order the status levels
dplyr::mutate(
EOSSTT = forcats::fct_relevel(EOSSTT, "DISCONTINUED", after = Inf)
)
tbl_study <-
# build initial table with the two summaries
tbl_summary(
data = adsl,
by = "TRT01A",
include = c("EOSSTT", "DCSREAS"),
# force the denominator to be out of total N, even when NA is present
percent = adsl,
missing = "no" # don't show NA counts
) |>
# now make a couple style changes to the table to match the spec
# 1. remove the header row for DCSREAS
remove_row_type(variables = "DCSREAS", type = "header") |>
# 2. indent DCSREAS levels (run `show_header_names()` to print column names)
modify_indent(
columns = "label",
rows = variable == "DCSREAS",
indent = 8L
)
Created on 2025-11-27 with reprex v2.1.1