rtables icon indicating copy to clipboard operation
rtables copied to clipboard

add_overall_col does not inherit colcounts from previous split

Open SHAESEN2 opened this issue 10 months ago • 3 comments

I would like to display N=xx for a total column but this option is not available from the function:

adsl <- data.frame(
  ARM = c("Placebo", "Placebo", "Treatment A", "Treatment A", "Treatment B", "Treatment B"),
  AGE = c(25, 30, 22, 28, 19, 45),
  SEX = c("Male", "Female", "Male", "Female", "Female", "Female")
)

add_combo <- rtables::add_combo_facet(
  "Combined",
  label = "Combined",
  levels = c("Treatment A", "Treatment B")
)

rm_combo_from_placebo <- cond_rm_facets(
  facets = "Combined",
  ancestor_pos = NA,
  value = " ",
  split = "ARM"
)

mysplit <- make_split_fun(post = list(add_combo, rm_combo_from_placebo))

basic_table() %>%
  split_cols_by("ARM", split_fun = mysplit, show_colcounts = TRUE, colcount_format = "N=xx") %>%
  add_overall_col("Total") %>%
  append_topleft("Mean Age \\super a") %>%
  analyze("AGE") %>%
  build_table(df = adsl)

                    Placebo   Treatment A   Treatment B   Combined        
Mean Age \super a     N=2         N=2           N=2         N=4      Total
——————————————————————————————————————————————————————————————————————————
Mean                 27.50       25.00         32.00       28.50     28.17

The only way of displaying the N = xx is to pass the arguments to basic_table, which is not always desired. Can add_overall_col be updated to fix this?

basic_table(show_colcounts = TRUE, colcount_format = "N=xx") %>%
  split_cols_by("ARM", split_fun = mysplit) %>%
  add_overall_col("Total") %>%
  append_topleft("Mean Age \\super a") %>%
  analyze("AGE") %>%
  build_table(df = adsl)

                    Placebo   Treatment A   Treatment B   Combined   Total
Mean Age \super a     N=2         N=2           N=2         N=4       N=6 
——————————————————————————————————————————————————————————————————————————
Mean                 27.50       25.00         32.00       28.50     28.17

SHAESEN2 avatar Apr 03 '25 13:04 SHAESEN2

Could you please use {reprex}? I get:

Error in cond_rm_facets(facets = "Combined", ancestor_pos = NA, value = " ",  : 
  could not find function "cond_rm_facets"

I get the following:

library(rtables)
# from ?add_combo_facet

mysplfun <- make_split_fun(post = list(
  add_combo_facet("A_B",
                  label = "Arms A+B",
                  levels = c("A: Drug X", "B: Placebo")
  ),
  add_overall_facet("ALL", label = "All Arms")
))

#this works for me
lyt <- basic_table() %>%
  add_colcounts() %>% 
  split_cols_by("ARM", split_fun = mysplfun) %>%
  analyze("AGE")

# Maybe this works?
lyt <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ARM", split_fun = mysplfun) %>%
  analyze("AGE")

build_table(lyt, DM)
#>        A: Drug X   B: Placebo   C: Combination   Arms A+B   All Arms
#>         (N=121)     (N=106)        (N=129)       (N=227)    (N=356) 
#> ————————————————————————————————————————————————————————————————————
#> Mean     34.91       33.02          34.57         34.03      34.22

Created on 2025-04-03 with reprex v2.1.1

Melkiades avatar Apr 03 '25 14:04 Melkiades

Thank you!

The solution works if only one column header is used, but when a spanning header is present it does not work anymore as this overall facet is added under each spanning level. I need to have a total across placebo and active.

adsl <- data.frame(
  span = c("Placebo", "Placebo", "Active", "Active", "Active", "Active"),
  ARM = c("Placebo", "Placebo", "Treatment A", "Treatment A", "Treatment B", "Treatment B"),
  AGE = c(25, 30, 22, 28, 19, 45),
  SEX = c("Male", "Female", "Male", "Female", "Female", "Female")
)

add_combo <- rtables::add_combo_facet(
  "Combined",
  label = "Combined",
  levels = c("Treatment A", "Treatment B")
)

mysplit <- make_split_fun(post = list(add_combo,  add_overall_facet("ALL", label = "All Arms")))

basic_table() %>%
  split_cols_by("ARM", split_fun = mysplit, show_colcounts = TRUE, colcount_format = "N=xx", nested = T) %>%
  add_overall_col("Total") %>%
  append_topleft("Mean Age") %>%
  analyze("AGE") %>%
  build_table(df = adsl)


           Placebo   Treatment A   Treatment B   Combined   All Arms        
Mean Age     N=2         N=2           N=2         N=4        N=6      Total
————————————————————————————————————————————————————————————————————————————
Mean        27.50       25.00         32.00       28.50      28.17     28.17


basic_table() %>%
  split_cols_by("span") %>%
  split_cols_by("ARM", split_fun = mysplit, show_colcounts = TRUE, colcount_format = "N=xx", nested = T) %>%
  add_overall_col("Total") %>%
  append_topleft("Mean Age") %>%
  analyze("AGE") %>%
  build_table(df = adsl)


                      Placebo                                  Active                             
           Placebo   Combined   All Arms   Treatment A   Treatment B   Combined   All Arms        
Mean Age     N=2       N=0        N=2          N=2           N=2         N=4        N=4      Total
——————————————————————————————————————————————————————————————————————————————————————————————————
Mean        27.50       NA       27.50        25.00         32.00       28.50      28.50     28.17

SHAESEN2 avatar Apr 03 '25 14:04 SHAESEN2

maybe you could just add it to add_overall_col("Total") %>% as a paste("Total N=", nrow())?

Have you tried also to add it manually with: rtables::col_counts()?

Melkiades avatar Jun 26 '25 14:06 Melkiades