rtables icon indicating copy to clipboard operation
rtables copied to clipboard

Enforce uniqueness of sibling names in row space

Open gmbecker opened this issue 9 months ago • 1 comments

Reporting an Issue with rtables

Normally, all paths in row space are "addressable", ie we can do

rdf <- make_rows_df(tbl)
pieces <- lapply(rdf$path, function(pth) tt_at_path(tbl, pth))

And everythig will work (we even have a test of this form in there somewhere.

Unfortunately, this is not guaranteed/enforced for all tables, specifically if we do

adsl <- ex_adsl
adsl$flag <- sample(c("Y", "N"), nrow(adsl), replace = TRUE)

afun <- function(x, ...) rcell(label = "Flagged Pop. Count", sum(x == "Y"))

lyt <- basic_table() %>%
  analyze("flag", afun = afun) %>%
  split_rows_by("flag", split_fun = keep_split_levels("Y"), child_labels = "hidden") %>%
  split_rows_by("SEX") %>%
  analyze("BMRKR1")

tbl <- build_table(lyt, adsl)

We get a table that builds and prints fine:

> tbl
                     all obs
————————————————————————————
Flagged Pop. Count     200  
F                           
  Mean                5.56  
M                           
  Mean                5.72  
U                           
  Mean                6.82  
UNDIFFERENTIATED            
  Mean                9.70

But

> lapply(make_row_df(tbl)$path, function(pth) tt_at_path(tbl, pth))
Error in tt_at_path(tbl, pth) :
Path appears invalid for this tree at step Y

In particulate, the issue is with any path starting with of the form

badpath <- c("root", "flag", "Y")
> tt_at_path(tbl, badpath)
Error in tt_at_path(tbl, badpath) : 
  Path appears invalid for this tree at step Y

We can see the reason in the table structure:

> table_structure(tbl)
[TableTree] root
 [ElementaryTable] flag (1 x 1)
 [TableTree] flag
  [TableTree] Y
   [TableTree] SEX
    [TableTree] F
     [ElementaryTable] BMRKR1 (1 x 1)
    [TableTree] M
     [ElementaryTable] BMRKR1 (1 x 1)
    [TableTree] U
     [ElementaryTable] BMRKR1 (1 x 1)
    [TableTree] UNDIFFERENTIATED
     [ElementaryTable] BMRKR1 (1 x 1)

Any path starting with c("root", "flag") is going to go into the Elementary table named flag and so it won't find any of the children of the TableTree flag. This is documented behavior, but still troublesome, so rtables should enforce siblings have unique names (the way it already does when analyzing the same variable twice).

Should be easy to detect and enforce (possibly with a warning/message) in the TableTree constructor. Note we need to be looking at and modifying obj_name of the incoming children, not just the names in the list object that holds the children.

This analyze and then split on flag variables is a pattern we are using in practice a fair bit, so the above example is quite realistic to our needs

gmbecker avatar Apr 25 '24 19:04 gmbecker