rtables icon indicating copy to clipboard operation
rtables copied to clipboard

Usual indexing does not work for reordering columns in a table

Open danielinteractive opened this issue 2 years ago • 4 comments

Hi @gmbecker and @waddella ,

I came across this little question today and it seems I am either missing something or rtables is missing something obvious.

Observation: The usual column indexing does not work for reordering columns in a table.

Example:

x <- rtable(c("A", "B"), rrow("row 1", 1,2), rrow("row 2", 3, 4))
x
x[, c(2, 1)] # is the same as x

Workaround works though:

cbind_rtables(x[, 2], x[, 1])

danielinteractive avatar Jul 06 '22 19:07 danielinteractive

Hi @danielinteractive,

So because rtables supports column spanning, tbl[, <out-of-order-indexes>] is...less unambiguous than you would expect in the general case. For Example, with the table:

> tbl <- rtable(header = c("A","A2", "B", "B2"), rrow("row", rcell(2, colspan = 2), rcell(5, colspan=2)))
> tbl
      A   A2   B   B2
—————————————————————
row     2        5   

What exactly should tbl[, c(1, 3, 2, 4)] do?

gmbecker avatar Jul 06 '22 20:07 gmbecker

Thanks @gmbecker for looking at this,

I understand that column spans complicate the semantics here. My expectations would be like this:

library(rtables)
tbl <- rtable(header = c("A","A2", "B", "B2"), rrow("row", rcell(2, colspan = 2), rcell(5, colspan=2)))
# A) Original table
tbl
# B) Subset
tbl[, c(1, 2)] # ok nice
# C) Another subset
tbl[, c(1, 2, 4)] # ok nice too
# D) Subset with changed order
tbl[, c(2, 1)] # why is this the same as B) ? No warning is given.
# Expected would be:
#
#      A2    A
# ————————————
# row     2

# Here the workaround is duplicating information but still correct from the contents:
cbind_rtables(tbl[, 2], tbl[, 1])

# E) Changed order across different colspans
tbl[, c(1, 3, 2, 4)] # why is this the same as A) ? No warning is given.
# Expected could be:
cbind_rtables(tbl[, 1], tbl[, 3], tbl[, 2], tbl[, 4])

danielinteractive avatar Jul 07 '22 08:07 danielinteractive

A deeper problem, now that I'm looking at it more, is when we have nested faceting structure in column space, e.g.,

>    lyt <- basic_table() %>%
+         split_cols_by("ARM") %>%
+         split_cols_by("STRATA1") %>%
+         analyze("AGE")
> tab <- build_table(lyt, DM)
> tab
             A: Drug X              B: Placebo            C: Combination    
         A       B       C       A       B       C       A       B       C  
————————————————————————————————————————————————————————————————————————————
Mean   32.53   35.46   36.34   32.30   32.42   34.45   35.76   34.39   33.54

In this case, doing tab[, c(2,1, 3, 4, 5, 6, 9, 7 8)] and getting

 cbind_rtables(tab[,2], tab[, 1], tab[,3], tab[,4], tab[,5], tab[,6], tab[,9], tab[,7], tab[,8])
       A: Drug X   A: Drug X   A: Drug X   B: Placebo   B: Placebo   B: Placebo   C: Combination   C: Combination   C: Combination
           B           A           C           A            B            C              C                A                B       
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Mean     35.46       32.53       36.34       32.30        32.42        34.45          33.54            35.76            34.39   

Is almost surely the wrong thing that's not what the user wanted.

What we probably want is a tree-structure aware rearrange_columns which would support the above case (and give the correct answer with only 3 top level headings with their children rearranged), but would probably error out for e.g., tab[, c(9, 1, 5, 2, 8, 3, 4, 7, 6)] where the reordering violates the hierarchical structure.

gmbecker avatar Jul 20 '22 22:07 gmbecker

thanks @gmbecker for thinking further about this. I agree that in this case the naive workaround is not giving a satisfactory result. How about thinking about a coding path where in a second step the column headings are merged between subsequent columns? (could be also an optional feature that is by default on but could be switched off by the user if not wished) I think that could be more flexible / user friendly rather than forbidding any reordering that violates the hierarchical structure.

danielinteractive avatar Jul 21 '22 13:07 danielinteractive

Closing as not-planned.

gmbecker avatar Aug 11 '23 23:08 gmbecker