Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hi @NNaikp, #33

Closed
gmbecker opened this issue Jan 6, 2022 · 0 comments
Closed

Hi @NNaikp, #33

gmbecker opened this issue Jan 6, 2022 · 0 comments

Comments

@gmbecker
Copy link
Collaborator

gmbecker commented Jan 6, 2022

Hi @NNaikp,

So speaking only for the approach you'd take with rtables, the typical table you'd make to display this set of information is slightly different (see below), but the key is that a) you can have distinct "analyses" that operate on different variables, and b) it's straightforward to write the analysis functions such that factor level, rather than observed values, dictates how many rows show up in an analysis block:

We'll use a slightly modified version of ex_adsl provided by rtables:

adsl2 <- ex_adsl
adsl2$smoker <- factor(NA, levels = c("10 cigarettes", ">10 cigarettes"))
adsl2$age_grp <- cut(adsl2$AGE, c(18, 65, 75, 1000), labels = c("18 <= to < 65",
                                                                "65 <= to < 75",
                                                                "Elderly >= 75"))

## make one of the factor levels of SEX variable empty
adsl2 <- subset(adsl2, SEX != "UNDIFFERENTIATED")

We then write an analysis function (which we will use for all the variables). Note if we didn't want the percentages there we would not need to specify the analysis function at all. Note here that analysis functions are passed the column observation count as .N_col and can use it in their computations during cell content generation, which we use here to get the percentages.

## helper that omits the pct entirely if the count is 0
count_pct <- function(x, .N_col, ...) {
    if( x == 0 ) {
        rcell(0, format = "xx")
    } else {
        rcell(c(x, x/.N_col), format = "xx (xx.x%)")
    }
}

## analysis function: table factor then apply above to get our cell values
tab_w_pct <- function(x, .N_col, ...) {
    tab <- as.list(table(x))
    lapply(tab, count_pct, .N_col = .N_col)
}

With that done the layout simply analyzes each of the desired variables:

lyt <- basic_table(show_colcounts = TRUE) %>%
    split_cols_by("ARM") %>%
    analyze("SEX", tab_w_pct, var_labels = "Gender") %>%
    analyze("smoker", tab_w_pct) %>%
    analyze("age_grp", tab_w_pct)


build_table(lyt, adsl2)

Which gives us

                      A: Drug X      B: Placebo    C: Combination
                       (N=133)        (N=134)         (N=130)    
—————————————————————————————————————————————————————————————————
Gender                                                           
  F                   79 (59.4%)     77 (57.5%)      66 (50.8%)  
  M                   51 (38.3%)     55 (41.0%)      60 (46.2%)  
  U                    3 (2.3%)       2 (1.5%)        4 (3.1%)   
  UNDIFFERENTIATED        0              0               0       
smoker                                                           
  10 cigarettes           0              0               0       
  >10 cigarettes          0              0               0       
age_grp                                                          
  18 <= to < 65      133 (100.0%)   134 (100.0%)    129 (99.2%)  
  65 <= to < 75           0              0            1 (0.8%)   
  Elderly >= 75           0              0               0       

Now as I noted this table is slightly different, as the patient counts are in the column header area rather than as a separate row.

To get something more exactly like the displayed table we could do:

lyt2 <- basic_table() %>%
    split_cols_by("ARM") %>%
    analyze("USUBJID", function(x) in_rows("Number of Patients" = length(unique(x))),
            show_labels = "hidden") %>%
    analyze("SEX", tab_w_pct, var_labels = "Gender") %>%
    analyze("smoker", tab_w_pct) %>%
    analyze("age_grp", tab_w_pct)


build_table(lyt2, adsl2)
                       A: Drug X      B: Placebo    C: Combination
—————————————————————————————————————————————————————————————————
Number of Patients       133            134             130      
Gender                                                           
  F                   79 (59.4%)     77 (57.5%)      66 (50.8%)  
  M                   51 (38.3%)     55 (41.0%)      60 (46.2%)  
  U                    3 (2.3%)       2 (1.5%)        4 (3.1%)   
  UNDIFFERENTIATED        0              0               0       
smoker                                                           
  10 cigarettes           0              0               0       
  >10 cigarettes          0              0               0       
age_grp                                                          
  18 <= to < 65      133 (100.0%)   134 (100.0%)    129 (99.2%)  
  65 <= to < 75           0              0            1 (0.8%)   
  Elderly >= 75           0              0               0       

Note that the percentages are still being calculated based on those column counts, not actually on the row cell values. Access to prior calculated rows counts/data is possible only for subtable structures an analysis is nested within.

If we wanted the total patient counts to be reprinted as context after pagination (which might make sense or very much not, depending on the goals), we would want that to be what we call a "group summary row" or more technically a "content row", which we would do like so:

lyt3 <- basic_table() %>%
    split_cols_by("ARM") %>%
    summarize_row_groups("USUBJID", label_fstr = "Number of Patients", format = "xx") %>%
    analyze("SEX", tab_w_pct, var_labels = "Gender", indent_mod = -1) %>%
    analyze("smoker", tab_w_pct, indent_mod = -1) %>%
    analyze("age_grp", tab_w_pct, indent_mod = -1)

tab <- build_table(lyt3, adsl2)

paginate_table(tab, lpp = 10)

Which gives us:

[[1]]
                     A: Drug X    B: Placebo   C: Combination
—————————————————————————————————————————————————————————————
Number of Patients      133          134            130      
Gender                                                       
  F                  79 (59.4%)   77 (57.5%)     66 (50.8%)  
  M                  51 (38.3%)   55 (41.0%)     60 (46.2%)  
  U                   3 (2.3%)     2 (1.5%)       4 (3.1%)   
  UNDIFFERENTIATED       0            0              0       

[[2]]
                      A: Drug X      B: Placebo    C: Combination
—————————————————————————————————————————————————————————————————
Number of Patients       133            134             130      
  smoker                                                         
    10 cigarettes         0              0               0       
    >10 cigarettes        0              0               0       
  age_grp                                                        
    18 <= to < 65    133 (100.0%)   134 (100.0%)    129 (99.2%)  
    65 <= to < 75         0              0            1 (0.8%)   
    Elderly >= 75         0              0               0       

Originally posted by @gmbecker in #32 (comment)

@gmbecker gmbecker closed this as completed Jan 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant