TLG Catalog - Stable
  • Stable
    • Dev
  1. Tables
  2. Lab Results
  3. LBT14
  • Introduction

  • Tables
    • ADA
      • ADAT01
      • ADAT02
      • ADAT03
      • ADAT04A
      • ADAT04B
    • Adverse Events
      • AET01
      • AET01_AESI
      • AET02
      • AET02_SMQ
      • AET03
      • AET04
      • AET04_PI
      • AET05
      • AET05_ALL
      • AET06
      • AET06_SMQ
      • AET07
      • AET09
      • AET09_SMQ
      • AET10
    • Concomitant Medications
      • CMT01
      • CMT01A
      • CMT01B
      • CMT02_PT
    • Deaths
      • DTHT01
    • Demography
      • DMT01
    • Disclosures
      • DISCLOSUREST01
      • EUDRAT01
      • EUDRAT02
    • Disposition
      • DST01
      • PDT01
      • PDT02
    • ECG
      • EGT01
      • EGT02
      • EGT03
      • EGT04
      • EGT05_QTCAT
    • Efficacy
      • AOVT01
      • AOVT02
      • AOVT03
      • CFBT01
      • CMHT01
      • COXT01
      • COXT02
      • DORT01
      • LGRT02
      • MMRMT01
      • ONCT05
      • RATET01
      • RBMIT01
      • RSPT01
      • TTET01
    • Exposure
      • EXT01
    • Lab Results
      • LBT01
      • LBT02
      • LBT03
      • LBT04
      • LBT05
      • LBT06
      • LBT07
      • LBT08
      • LBT09
      • LBT10
      • LBT10_BL
      • LBT11
      • LBT11_BL
      • LBT12
      • LBT12_BL
      • LBT13
      • LBT14
      • LBT15
    • Medical History
      • MHT01
    • Pharmacokinetic
      • PKCT01
      • PKPT02
      • PKPT03
      • PKPT04
      • PKPT05
      • PKPT06
      • PKPT07
      • PKPT08
      • PKPT11
    • Risk Management Plan
      • RMPT01
      • RMPT03
      • RMPT04
      • RMPT05
      • RMPT06
    • Safety
      • ENTXX
    • Vital Signs
      • VST01
      • VST02
  • Listings
    • ADA
      • ADAL02
    • Adverse Events
      • AEL01
      • AEL01_NOLLT
      • AEL02
      • AEL02_ED
      • AEL03
      • AEL04
    • Concomitant Medications
      • CML01
      • CML02A_GL
      • CML02B_GL
    • Development Safety Update Report
      • DSUR4
    • Disposition
      • DSL01
      • DSL02
    • ECG
      • EGL01
    • Efficacy
      • ONCL01
    • Exposure
      • EXL01
    • Lab Results
      • LBL01
      • LBL01_RLS
      • LBL02A
      • LBL02A_RLS
      • LBL02B
    • Medical History
      • MHL01
    • Pharmacokinetic
      • ADAL01
      • PKCL01
      • PKCL02
      • PKPL01
      • PKPL02
      • PKPL04
    • Vital Signs
      • VSL01
  • Graphs
    • Efficacy
      • FSTG01
      • FSTG02
      • KMG01
      • MMRMG01
      • MMRMG02
    • Other
      • BRG01
      • BWG01
      • CIG01
      • IPPG01
      • LTG01
      • MNG01
    • Pharmacokinetic
      • PKCG01
      • PKCG02
      • PKCG03
      • PKPG01
      • PKPG02
      • PKPG03
      • PKPG04
      • PKPG06

  • Appendix
    • Reproducibility

  • Index

On this page

  • Output
  • teal App
  • Reproducibility
    • Timestamp
    • Session Info
    • .lock file
  • Edit this page
  • Report an issue
  1. Tables
  2. Lab Results
  3. LBT14

LBT14

Laboratory Test Results Shift Table – Highest NCI CTCAE Grade Post-Baseline by Baseline NCI CTCAE Grade


Output

  • Standard Table (High)
  • Standard Table (Low)
  • Table Without Patients with
    Missing Baseline (High)
  • Table with Missing Baseline
    Considered as Grade 0 (Low)
  • Table with Fill-In of Grades
  • Data Setup

Note that the worst laboratory flag (below WGRHIFL) must be selected appropriately in the pre-processing step. New grouping variables ATOXGR_GP (post-baseline) and BTOXGR_GP (baseline) are created to display the correct output.

  • Preview
  • Try this using WebR
Code
adlb_f <- adlb %>% filter(WGRHIFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRHIFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      ATOXGR == 1 ~ "1",
      ATOXGR == 2 ~ "2",
      ATOXGR == 3 ~ "3",
      ATOXGR == 4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      BTOXGR == 1 ~ "1",
      BTOXGR == 2 ~ "2",
      BTOXGR == 3 ~ "3",
      BTOXGR == 4 ~ "4",
      BTOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f) %>%
  prune_table()

result
Parameter                                                                             
      Baseline NCI-CTCAE Grade                A: Drug X    B: Placebo   C: Combination
              Post-baseline NCI-CTCAE Grade    (N=134)      (N=134)        (N=132)    
——————————————————————————————————————————————————————————————————————————————————————
Alanine Aminotransferase Measurement                                                  
      Not High                                   134          134            132      
              Not High                        134 (100%)   134 (100%)     132 (100%)  
C-Reactive Protein Measurement                                                        
      Not High                                   114          112            115      
              Not High                        45 (39.5%)   55 (49.1%)     57 (49.6%)  
              1                               18 (15.8%)   18 (16.1%)     19 (16.5%)  
              2                               19 (16.7%)   10 (8.9%)      11 (9.6%)   
              3                               22 (19.3%)   13 (11.6%)     20 (17.4%)  
              4                               10 (8.8%)    16 (14.3%)      8 (7.0%)   
      1                                           8            10             7       
              Not High                        5 (62.5%)    2 (20.0%)      2 (28.6%)   
              1                                   0        1 (10.0%)          0       
              2                               1 (12.5%)    3 (30.0%)      3 (42.9%)   
              3                               1 (12.5%)    1 (10.0%)          0       
              4                               1 (12.5%)    3 (30.0%)      2 (28.6%)   
      2                                           2            6              7       
              Not High                        1 (50.0%)    4 (66.7%)      4 (57.1%)   
              1                                   0        1 (16.7%)      2 (28.6%)   
              2                               1 (50.0%)    1 (16.7%)          0       
              4                                   0            0          1 (14.3%)   
      3                                           7            4              3       
              Not High                        3 (42.9%)        0          2 (66.7%)   
              1                               2 (28.6%)    1 (25.0%)      1 (33.3%)   
              2                                   0        1 (25.0%)          0       
              3                               1 (14.3%)    1 (25.0%)          0       
              4                               1 (14.3%)    1 (25.0%)          0       
      4                                           3            2              0       
              Not High                        1 (33.3%)        0              0       
              1                                   0        1 (50.0%)          0       
              3                               1 (33.3%)    1 (50.0%)          0       
              4                               1 (33.3%)        0              0       
Immunoglobulin A Measurement                                                          
      Not High                                   119          116            113      
              Not High                        55 (46.2%)   54 (46.6%)     51 (45.1%)  
              1                               18 (15.1%)   11 (9.5%)      15 (13.3%)  
              2                               14 (11.8%)   22 (19.0%)     19 (16.8%)  
              3                               20 (16.8%)   19 (16.4%)     20 (17.7%)  
              4                               12 (10.1%)   10 (8.6%)       8 (7.1%)   
      1                                           5            4              2       
              Not High                        4 (80.0%)    1 (25.0%)       2 (100%)   
              2                               1 (20.0%)    1 (25.0%)          0       
              3                                   0        2 (50.0%)          0       
      2                                           4            4              5       
              Not High                        2 (50.0%)    3 (75.0%)      3 (60.0%)   
              1                               1 (25.0%)        0          2 (40.0%)   
              3                               1 (25.0%)        0              0       
              4                                   0        1 (25.0%)          0       
      3                                           4            5              11      
              Not High                        3 (75.0%)    1 (20.0%)      6 (54.5%)   
              1                                   0        1 (20.0%)       1 (9.1%)   
              2                               1 (25.0%)        0              0       
              3                                   0        2 (40.0%)      3 (27.3%)   
              4                                   0        1 (20.0%)       1 (9.1%)   
      4                                           2            5              1       
              Not High                            0        3 (60.0%)       1 (100%)   
              2                               1 (50.0%)    1 (20.0%)          0       
              4                               1 (50.0%)    1 (20.0%)          0       
WarningExperimental use!

WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.

Note that the worst laboratory flag (below WGRLOFL) must be selected appropriately in the pre-processing step. New grouping variables ATOXGR_GP (post-baseline) and BTOXGR_GP (baseline) are created to display the correct output.

  • Preview
  • Try this using WebR
Code
adlb_f <- adlb %>% filter(WGRLOFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRLOFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, 1, 2, 3, 4) ~ "Not Low",
      ATOXGR == -1 ~ "1",
      ATOXGR == -2 ~ "2",
      ATOXGR == -3 ~ "3",
      ATOXGR == -4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not Low", "1", "2", "3", "4", "Missing"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, 1, 2, 3, 4) ~ "Not Low",
      BTOXGR == -1 ~ "1",
      BTOXGR == -2 ~ "2",
      BTOXGR == -3 ~ "3",
      BTOXGR == -4 ~ "4",
      BTOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not Low", "1", "2", "3", "4", "Missing"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f) %>%
  prune_table()

result
Parameter                                                                             
      Baseline NCI-CTCAE Grade                A: Drug X    B: Placebo   C: Combination
              Post-baseline NCI-CTCAE Grade    (N=134)      (N=134)        (N=132)    
——————————————————————————————————————————————————————————————————————————————————————
Alanine Aminotransferase Measurement                                                  
      Not Low                                    113          117            123      
              Not Low                         56 (49.6%)   55 (47.0%)     62 (50.4%)  
              1                               11 (9.7%)     9 (7.7%)      15 (12.2%)  
              2                               15 (13.3%)   23 (19.7%)     16 (13.0%)  
              3                               15 (13.3%)   21 (17.9%)     13 (10.6%)  
              4                               16 (14.2%)    9 (7.7%)      17 (13.8%)  
      1                                           6            6              4       
              Not Low                         3 (50.0%)    5 (83.3%)      3 (75.0%)   
              1                               3 (50.0%)        0              0       
              4                                   0        1 (16.7%)      1 (25.0%)   
      2                                           8            5              1       
              Not Low                         5 (62.5%)    3 (60.0%)          0       
              1                                   0        1 (20.0%)          0       
              2                               2 (25.0%)        0              0       
              3                                   0        1 (20.0%)       1 (100%)   
              4                               1 (12.5%)        0              0       
      3                                           3            3              2       
              Not Low                             0        1 (33.3%)          0       
              1                               1 (33.3%)        0              0       
              2                               1 (33.3%)        0          1 (50.0%)   
              3                               1 (33.3%)    2 (66.7%)      1 (50.0%)   
      4                                           4            3              2       
              Not Low                          4 (100%)    1 (33.3%)      1 (50.0%)   
              1                                   0        1 (33.3%)          0       
              2                                   0        1 (33.3%)          0       
              3                                   0            0          1 (50.0%)   
C-Reactive Protein Measurement                                                        
      Not Low                                    119          113            112      
              Not Low                         41 (34.5%)   42 (37.2%)     50 (44.6%)  
              1                               20 (16.8%)   18 (15.9%)     11 (9.8%)   
              2                               24 (20.2%)   20 (17.7%)     14 (12.5%)  
              3                               25 (21.0%)   18 (15.9%)     21 (18.8%)  
              4                                9 (7.6%)    15 (13.3%)     16 (14.3%)  
      1                                           3            5              9       
              Not Low                         2 (66.7%)    2 (40.0%)      2 (22.2%)   
              2                                   0        1 (20.0%)      3 (33.3%)   
              3                               1 (33.3%)    1 (20.0%)          0       
              4                                   0        1 (20.0%)      4 (44.4%)   
      2                                           5            9              2       
              Not Low                         3 (60.0%)    4 (44.4%)      1 (50.0%)   
              1                               1 (20.0%)    4 (44.4%)          0       
              3                                   0        1 (11.1%)      1 (50.0%)   
              4                               1 (20.0%)        0              0       
      3                                           4            5              7       
              Not Low                         1 (25.0%)    4 (80.0%)      2 (28.6%)   
              1                                   0            0          1 (14.3%)   
              2                                   0            0          1 (14.3%)   
              3                               3 (75.0%)    1 (20.0%)      2 (28.6%)   
              4                                   0            0          1 (14.3%)   
      4                                           3            2              2       
              Not Low                          3 (100%)    1 (50.0%)          0       
              2                                   0        1 (50.0%)          0       
              3                                   0            0          1 (50.0%)   
              4                                   0            0          1 (50.0%)   
Immunoglobulin A Measurement                                                          
      Not Low                                    134          134            132      
              Not Low                         134 (100%)   134 (100%)     132 (100%)  
WarningExperimental use!

WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.

Note that missing baseline values are filtered out in the pre-processing step.

  • Preview
  • Try this using WebR
Code
adlb_f <- adlb %>% filter(WGRHIFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRHIFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  filter(BTOXGR != "<Missing>") %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      ATOXGR == 1 ~ "1",
      ATOXGR == 2 ~ "2",
      ATOXGR == 3 ~ "3",
      ATOXGR == 4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      BTOXGR == 1 ~ "1",
      BTOXGR == 2 ~ "2",
      BTOXGR == 3 ~ "3",
      BTOXGR == 4 ~ "4"
    ), levels = c("Not High", "1", "2", "3", "4"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f) %>%
  prune_table()

result
Parameter                                                                             
      Baseline NCI-CTCAE Grade                A: Drug X    B: Placebo   C: Combination
              Post-baseline NCI-CTCAE Grade    (N=134)      (N=134)        (N=132)    
——————————————————————————————————————————————————————————————————————————————————————
Alanine Aminotransferase Measurement                                                  
      Not High                                   134          134            132      
              Not High                        134 (100%)   134 (100%)     132 (100%)  
C-Reactive Protein Measurement                                                        
      Not High                                   114          112            115      
              Not High                        45 (39.5%)   55 (49.1%)     57 (49.6%)  
              1                               18 (15.8%)   18 (16.1%)     19 (16.5%)  
              2                               19 (16.7%)   10 (8.9%)      11 (9.6%)   
              3                               22 (19.3%)   13 (11.6%)     20 (17.4%)  
              4                               10 (8.8%)    16 (14.3%)      8 (7.0%)   
      1                                           8            10             7       
              Not High                        5 (62.5%)    2 (20.0%)      2 (28.6%)   
              1                                   0        1 (10.0%)          0       
              2                               1 (12.5%)    3 (30.0%)      3 (42.9%)   
              3                               1 (12.5%)    1 (10.0%)          0       
              4                               1 (12.5%)    3 (30.0%)      2 (28.6%)   
      2                                           2            6              7       
              Not High                        1 (50.0%)    4 (66.7%)      4 (57.1%)   
              1                                   0        1 (16.7%)      2 (28.6%)   
              2                               1 (50.0%)    1 (16.7%)          0       
              4                                   0            0          1 (14.3%)   
      3                                           7            4              3       
              Not High                        3 (42.9%)        0          2 (66.7%)   
              1                               2 (28.6%)    1 (25.0%)      1 (33.3%)   
              2                                   0        1 (25.0%)          0       
              3                               1 (14.3%)    1 (25.0%)          0       
              4                               1 (14.3%)    1 (25.0%)          0       
      4                                           3            2              0       
              Not High                        1 (33.3%)        0              0       
              1                                   0        1 (50.0%)          0       
              3                               1 (33.3%)    1 (50.0%)          0       
              4                               1 (33.3%)        0              0       
Immunoglobulin A Measurement                                                          
      Not High                                   119          116            113      
              Not High                        55 (46.2%)   54 (46.6%)     51 (45.1%)  
              1                               18 (15.1%)   11 (9.5%)      15 (13.3%)  
              2                               14 (11.8%)   22 (19.0%)     19 (16.8%)  
              3                               20 (16.8%)   19 (16.4%)     20 (17.7%)  
              4                               12 (10.1%)   10 (8.6%)       8 (7.1%)   
      1                                           5            4              2       
              Not High                        4 (80.0%)    1 (25.0%)       2 (100%)   
              2                               1 (20.0%)    1 (25.0%)          0       
              3                                   0        2 (50.0%)          0       
      2                                           4            4              5       
              Not High                        2 (50.0%)    3 (75.0%)      3 (60.0%)   
              1                               1 (25.0%)        0          2 (40.0%)   
              3                               1 (25.0%)        0              0       
              4                                   0        1 (25.0%)          0       
      3                                           4            5              11      
              Not High                        3 (75.0%)    1 (20.0%)      6 (54.5%)   
              1                                   0        1 (20.0%)       1 (9.1%)   
              2                               1 (25.0%)        0              0       
              3                                   0        2 (40.0%)      3 (27.3%)   
              4                                   0        1 (20.0%)       1 (9.1%)   
      4                                           2            5              1       
              Not High                            0        3 (60.0%)       1 (100%)   
              2                               1 (50.0%)    1 (20.0%)          0       
              4                               1 (50.0%)    1 (20.0%)          0       
WarningExperimental use!

WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.

Note that when BTOXGR is missing, the grouping variable BTOXGR_GP now is "Not Low" instead of "Missing" compared to Standard Table (Low).

  • Preview
  • Try this using WebR
Code
adlb_f <- adlb %>% filter(WGRLOFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRLOFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, 1, 2, 3, 4) ~ "Not Low",
      ATOXGR == -1 ~ "1",
      ATOXGR == -2 ~ "2",
      ATOXGR == -3 ~ "3",
      ATOXGR == -4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not Low", "1", "2", "3", "4"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, 1, 2, 3, 4, "<Missing>") ~ "Not Low",
      BTOXGR == -1 ~ "1",
      BTOXGR == -2 ~ "2",
      BTOXGR == -3 ~ "3",
      BTOXGR == -4 ~ "4"
    ), levels = c("Not Low", "1", "2", "3", "4", "Missing"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f) %>%
  prune_table()

result
Parameter                                                                             
      Baseline NCI-CTCAE Grade                A: Drug X    B: Placebo   C: Combination
              Post-baseline NCI-CTCAE Grade    (N=134)      (N=134)        (N=132)    
——————————————————————————————————————————————————————————————————————————————————————
Alanine Aminotransferase Measurement                                                  
      Not Low                                    113          117            123      
              Not Low                         56 (49.6%)   55 (47.0%)     62 (50.4%)  
              1                               11 (9.7%)     9 (7.7%)      15 (12.2%)  
              2                               15 (13.3%)   23 (19.7%)     16 (13.0%)  
              3                               15 (13.3%)   21 (17.9%)     13 (10.6%)  
              4                               16 (14.2%)    9 (7.7%)      17 (13.8%)  
      1                                           6            6              4       
              Not Low                         3 (50.0%)    5 (83.3%)      3 (75.0%)   
              1                               3 (50.0%)        0              0       
              4                                   0        1 (16.7%)      1 (25.0%)   
      2                                           8            5              1       
              Not Low                         5 (62.5%)    3 (60.0%)          0       
              1                                   0        1 (20.0%)          0       
              2                               2 (25.0%)        0              0       
              3                                   0        1 (20.0%)       1 (100%)   
              4                               1 (12.5%)        0              0       
      3                                           3            3              2       
              Not Low                             0        1 (33.3%)          0       
              1                               1 (33.3%)        0              0       
              2                               1 (33.3%)        0          1 (50.0%)   
              3                               1 (33.3%)    2 (66.7%)      1 (50.0%)   
      4                                           4            3              2       
              Not Low                          4 (100%)    1 (33.3%)      1 (50.0%)   
              1                                   0        1 (33.3%)          0       
              2                                   0        1 (33.3%)          0       
              3                                   0            0          1 (50.0%)   
C-Reactive Protein Measurement                                                        
      Not Low                                    119          113            112      
              Not Low                         41 (34.5%)   42 (37.2%)     50 (44.6%)  
              1                               20 (16.8%)   18 (15.9%)     11 (9.8%)   
              2                               24 (20.2%)   20 (17.7%)     14 (12.5%)  
              3                               25 (21.0%)   18 (15.9%)     21 (18.8%)  
              4                                9 (7.6%)    15 (13.3%)     16 (14.3%)  
      1                                           3            5              9       
              Not Low                         2 (66.7%)    2 (40.0%)      2 (22.2%)   
              2                                   0        1 (20.0%)      3 (33.3%)   
              3                               1 (33.3%)    1 (20.0%)          0       
              4                                   0        1 (20.0%)      4 (44.4%)   
      2                                           5            9              2       
              Not Low                         3 (60.0%)    4 (44.4%)      1 (50.0%)   
              1                               1 (20.0%)    4 (44.4%)          0       
              3                                   0        1 (11.1%)      1 (50.0%)   
              4                               1 (20.0%)        0              0       
      3                                           4            5              7       
              Not Low                         1 (25.0%)    4 (80.0%)      2 (28.6%)   
              1                                   0            0          1 (14.3%)   
              2                                   0            0          1 (14.3%)   
              3                               3 (75.0%)    1 (20.0%)      2 (28.6%)   
              4                                   0            0          1 (14.3%)   
      4                                           3            2              2       
              Not Low                          3 (100%)    1 (50.0%)          0       
              2                                   0        1 (50.0%)          0       
              3                                   0            0          1 (50.0%)   
              4                                   0            0          1 (50.0%)   
Immunoglobulin A Measurement                                                          
      Not Low                                    134          134            132      
              Not Low                         134 (100%)   134 (100%)     132 (100%)  
WarningExperimental use!

WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.

Pre-processing is the same as Standard Table (High), but in order to keep all levels, prune_table() is not applied.

  • Preview
  • Try this using WebR
Code
adlb_f <- adlb %>% filter(WGRHIFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRHIFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      ATOXGR == 1 ~ "1",
      ATOXGR == 2 ~ "2",
      ATOXGR == 3 ~ "3",
      ATOXGR == 4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      BTOXGR == 1 ~ "1",
      BTOXGR == 2 ~ "2",
      BTOXGR == 3 ~ "3",
      BTOXGR == 4 ~ "4",
      BTOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f)

result
Parameter                                                                             
      Baseline NCI-CTCAE Grade                A: Drug X    B: Placebo   C: Combination
              Post-baseline NCI-CTCAE Grade    (N=134)      (N=134)        (N=132)    
——————————————————————————————————————————————————————————————————————————————————————
Alanine Aminotransferase Measurement                                                  
      Not High                                   134          134            132      
              Not High                        134 (100%)   134 (100%)     132 (100%)  
              1                                   0            0              0       
              2                                   0            0              0       
              3                                   0            0              0       
              4                                   0            0              0       
              Missing                             0            0              0       
      1                                           0            0              0       
              Not High                            0            0              0       
              1                                   0            0              0       
              2                                   0            0              0       
              3                                   0            0              0       
              4                                   0            0              0       
              Missing                             0            0              0       
      2                                           0            0              0       
              Not High                            0            0              0       
              1                                   0            0              0       
              2                                   0            0              0       
              3                                   0            0              0       
              4                                   0            0              0       
              Missing                             0            0              0       
      3                                           0            0              0       
              Not High                            0            0              0       
              1                                   0            0              0       
              2                                   0            0              0       
              3                                   0            0              0       
              4                                   0            0              0       
              Missing                             0            0              0       
      4                                           0            0              0       
              Not High                            0            0              0       
              1                                   0            0              0       
              2                                   0            0              0       
              3                                   0            0              0       
              4                                   0            0              0       
              Missing                             0            0              0       
      Missing                                     0            0              0       
              Not High                            0            0              0       
              1                                   0            0              0       
              2                                   0            0              0       
              3                                   0            0              0       
              4                                   0            0              0       
              Missing                             0            0              0       
C-Reactive Protein Measurement                                                        
      Not High                                   114          112            115      
              Not High                        45 (39.5%)   55 (49.1%)     57 (49.6%)  
              1                               18 (15.8%)   18 (16.1%)     19 (16.5%)  
              2                               19 (16.7%)   10 (8.9%)      11 (9.6%)   
              3                               22 (19.3%)   13 (11.6%)     20 (17.4%)  
              4                               10 (8.8%)    16 (14.3%)      8 (7.0%)   
              Missing                             0            0              0       
      1                                           8            10             7       
              Not High                        5 (62.5%)    2 (20.0%)      2 (28.6%)   
              1                                   0        1 (10.0%)          0       
              2                               1 (12.5%)    3 (30.0%)      3 (42.9%)   
              3                               1 (12.5%)    1 (10.0%)          0       
              4                               1 (12.5%)    3 (30.0%)      2 (28.6%)   
              Missing                             0            0              0       
      2                                           2            6              7       
              Not High                        1 (50.0%)    4 (66.7%)      4 (57.1%)   
              1                                   0        1 (16.7%)      2 (28.6%)   
              2                               1 (50.0%)    1 (16.7%)          0       
              3                                   0            0              0       
              4                                   0            0          1 (14.3%)   
              Missing                             0            0              0       
      3                                           7            4              3       
              Not High                        3 (42.9%)        0          2 (66.7%)   
              1                               2 (28.6%)    1 (25.0%)      1 (33.3%)   
              2                                   0        1 (25.0%)          0       
              3                               1 (14.3%)    1 (25.0%)          0       
              4                               1 (14.3%)    1 (25.0%)          0       
              Missing                             0            0              0       
      4                                           3            2              0       
              Not High                        1 (33.3%)        0              0       
              1                                   0        1 (50.0%)          0       
              2                                   0            0              0       
              3                               1 (33.3%)    1 (50.0%)          0       
              4                               1 (33.3%)        0              0       
              Missing                             0            0              0       
      Missing                                     0            0              0       
              Not High                            0            0              0       
              1                                   0            0              0       
              2                                   0            0              0       
              3                                   0            0              0       
              4                                   0            0              0       
              Missing                             0            0              0       
Immunoglobulin A Measurement                                                          
      Not High                                   119          116            113      
              Not High                        55 (46.2%)   54 (46.6%)     51 (45.1%)  
              1                               18 (15.1%)   11 (9.5%)      15 (13.3%)  
              2                               14 (11.8%)   22 (19.0%)     19 (16.8%)  
              3                               20 (16.8%)   19 (16.4%)     20 (17.7%)  
              4                               12 (10.1%)   10 (8.6%)       8 (7.1%)   
              Missing                             0            0              0       
      1                                           5            4              2       
              Not High                        4 (80.0%)    1 (25.0%)       2 (100%)   
              1                                   0            0              0       
              2                               1 (20.0%)    1 (25.0%)          0       
              3                                   0        2 (50.0%)          0       
              4                                   0            0              0       
              Missing                             0            0              0       
      2                                           4            4              5       
              Not High                        2 (50.0%)    3 (75.0%)      3 (60.0%)   
              1                               1 (25.0%)        0          2 (40.0%)   
              2                                   0            0              0       
              3                               1 (25.0%)        0              0       
              4                                   0        1 (25.0%)          0       
              Missing                             0            0              0       
      3                                           4            5              11      
              Not High                        3 (75.0%)    1 (20.0%)      6 (54.5%)   
              1                                   0        1 (20.0%)       1 (9.1%)   
              2                               1 (25.0%)        0              0       
              3                                   0        2 (40.0%)      3 (27.3%)   
              4                                   0        1 (20.0%)       1 (9.1%)   
              Missing                             0            0              0       
      4                                           2            5              1       
              Not High                            0        3 (60.0%)       1 (100%)   
              1                                   0            0              0       
              2                               1 (50.0%)    1 (20.0%)          0       
              3                                   0            0              0       
              4                               1 (50.0%)    1 (20.0%)          0       
              Missing                             0            0              0       
      Missing                                     0            0              0       
              Not High                            0            0              0       
              1                                   0            0              0       
              2                                   0            0              0       
              3                                   0            0              0       
              4                                   0            0              0       
              Missing                             0            0              0       
WarningExperimental use!

WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.

Please note that for each variant, the adlb dataset needs to be filtered on correct flags like WGRLOFL, WGRHIFL, et al., otherwise the layout function will not return the correct counts. There is an option to create a record for a lab test where no record is found at that visit. If you specified add_derived_type = "PHANTOM" & dtype_phantom_cond, you don’t have to use the h_adsl_adlb_merge_using_worst_flag function to preprocess your adlb dataset. Otherwise please follow the pre-processing steps below before applying the layout functions.

Code
library(dplyr)
library(tern)

adsl <- random.cdisc.data::cadsl
adlb <- random.cdisc.data::cadlb

adsl <- df_explicit_na(adsl)
adlb <- df_explicit_na(adlb)

# Please note that in real clinical data, population flag like SAFFL, and parameter category like PARCAT2 needs to be
# selected properly.
adsl_f <- adsl %>% filter(SAFFL == "Y")
adlb <- adlb %>% filter(SAFFL == "Y")

teal App

  • Preview
  • Try this using shinylive
Code
library(teal.modules.clinical)

## Data reproducible code
data <- teal_data()
data <- within(data, {
  ADSL <- random.cdisc.data::cadsl
  ADLB <- random.cdisc.data::cadlb
})
join_keys(data) <- default_cdisc_join_keys[c("ADSL", "ADLB")]

## Reusable Configuration For Modules
ADSL <- data[["ADSL"]]
ADLB <- data[["ADLB"]]

## Setup App
app <- init(
  data = data,
  modules = modules(
    tm_t_shift_by_grade(
      label = "Grade Laboratory Abnormality Table",
      dataname = "ADLB",
      arm_var = choices_selected(
        choices = variable_choices(ADSL, subset = c("ARM", "ARMCD")),
        selected = "ARM"
      ),
      paramcd = choices_selected(
        choices = value_choices(ADLB, "PARAMCD", "PARAM"),
        selected = "ALT"
      ),
      worst_flag_var = choices_selected(
        choices = variable_choices(ADLB, subset = c("WGRLOVFL", "WGRLOFL", "WGRHIVFL", "WGRHIFL")),
        selected = c("WGRHIFL")
      ),
      worst_flag_indicator = choices_selected(
        value_choices(ADLB, "WGRLOVFL"),
        selected = "Y", fixed = TRUE
      ),
      anl_toxgrade_var = choices_selected(
        choices = variable_choices(ADLB, subset = c("ATOXGR")),
        selected = c("ATOXGR"),
        fixed = TRUE
      ),
      base_toxgrade_var = choices_selected(
        choices = variable_choices(ADLB, subset = c("BTOXGR")),
        selected = c("BTOXGR"),
        fixed = TRUE
      ),
      add_total = FALSE
    )
  ),
  filter = teal_slices(teal_slice("ADSL", "SAFFL", selected = "Y"))
)

shinyApp(app$ui, app$server)

WarningExperimental use!

shinylive allow you to modify to run shiny application entirely in the web browser. Modify the code below and click re-run the app to see the results. The performance is slighly worse and some of the features (e.g. downloading) might not work at all.

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 800
#| editorHeight: 200
#| components: [viewer, editor]
#| layout: vertical

# -- WEBR HELPERS --
options(webr_pkg_repos = c("r-universe" = "https://insightsengineering.r-universe.dev", getOption("webr_pkg_repos")))

# -- APP CODE --
library(teal.modules.clinical)

## Data reproducible code
data <- teal_data()
data <- within(data, {
  ADSL <- random.cdisc.data::cadsl
  ADLB <- random.cdisc.data::cadlb
})
join_keys(data) <- default_cdisc_join_keys[c("ADSL", "ADLB")]

## Reusable Configuration For Modules
ADSL <- data[["ADSL"]]
ADLB <- data[["ADLB"]]

## Setup App
app <- init(
  data = data,
  modules = modules(
    tm_t_shift_by_grade(
      label = "Grade Laboratory Abnormality Table",
      dataname = "ADLB",
      arm_var = choices_selected(
        choices = variable_choices(ADSL, subset = c("ARM", "ARMCD")),
        selected = "ARM"
      ),
      paramcd = choices_selected(
        choices = value_choices(ADLB, "PARAMCD", "PARAM"),
        selected = "ALT"
      ),
      worst_flag_var = choices_selected(
        choices = variable_choices(ADLB, subset = c("WGRLOVFL", "WGRLOFL", "WGRHIVFL", "WGRHIFL")),
        selected = c("WGRHIFL")
      ),
      worst_flag_indicator = choices_selected(
        value_choices(ADLB, "WGRLOVFL"),
        selected = "Y", fixed = TRUE
      ),
      anl_toxgrade_var = choices_selected(
        choices = variable_choices(ADLB, subset = c("ATOXGR")),
        selected = c("ATOXGR"),
        fixed = TRUE
      ),
      base_toxgrade_var = choices_selected(
        choices = variable_choices(ADLB, subset = c("BTOXGR")),
        selected = c("BTOXGR"),
        fixed = TRUE
      ),
      add_total = FALSE
    )
  ),
  filter = teal_slices(teal_slice("ADSL", "SAFFL", selected = "Y"))
)

shinyApp(app$ui, app$server)

Reproducibility

Timestamp

[1] "2026-06-17 18:17:33 UTC"

Session Info

─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.5.2 (2025-10-31)
 os       Ubuntu 24.04.4 LTS
 system   x86_64, linux-gnu
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       Etc/UTC
 date     2026-06-17
 pandoc   3.9 @ /usr/bin/ (via rmarkdown)
 quarto   1.9.38 @ /usr/local/bin/quarto

─ Packages ───────────────────────────────────────────────────────────────────
 package               * version   date (UTC) lib source
 backports               1.5.1     2026-04-03 [1] CRAN (R 4.5.2)
 brio                    1.1.5     2024-04-24 [1] CRAN (R 4.5.2)
 broom                   1.0.13    2026-05-14 [1] CRAN (R 4.5.2)
 bsicons                 0.1.2     2023-11-04 [1] CRAN (R 4.5.2)
 bslib                   0.11.0    2026-05-16 [1] CRAN (R 4.5.2)
 cachem                  1.1.0     2024-05-16 [1] CRAN (R 4.5.2)
 callr                   3.8.0     2026-06-05 [1] CRAN (R 4.5.2)
 checkmate               2.3.4     2026-02-03 [1] CRAN (R 4.5.2)
 chromote                0.5.1     2025-04-24 [1] CRAN (R 4.5.2)
 cli                     3.6.6     2026-04-09 [1] CRAN (R 4.5.2)
 codetools               0.2-20    2024-03-31 [2] CRAN (R 4.5.2)
 curl                    7.1.0     2026-04-22 [1] CRAN (R 4.5.2)
 dichromat               2.0-0.1   2022-05-02 [1] CRAN (R 4.5.2)
 digest                  0.6.39    2025-11-19 [1] CRAN (R 4.5.2)
 dplyr                 * 1.2.1     2026-04-03 [1] CRAN (R 4.5.2)
 evaluate                1.0.5     2025-08-27 [1] CRAN (R 4.5.2)
 farver                  2.1.2     2024-05-13 [1] CRAN (R 4.5.2)
 fastmap                 1.2.0     2024-05-15 [1] CRAN (R 4.5.2)
 fontawesome             0.5.3     2024-11-16 [1] CRAN (R 4.5.2)
 forcats                 1.0.1     2025-09-25 [1] CRAN (R 4.5.2)
 formatR                 1.14      2023-01-17 [1] CRAN (R 4.5.2)
 formatters            * 0.5.12    2025-12-08 [1] CRAN (R 4.5.2)
 fs                      2.1.0     2026-04-18 [1] CRAN (R 4.5.2)
 generics                0.1.4     2025-05-09 [1] CRAN (R 4.5.2)
 ggplot2                 4.0.3     2026-04-22 [1] CRAN (R 4.5.2)
 glue                    1.8.1     2026-04-17 [1] CRAN (R 4.5.2)
 gtable                  0.3.6     2024-10-25 [1] CRAN (R 4.5.2)
 htmltools               0.5.9     2025-12-04 [1] CRAN (R 4.5.2)
 htmlwidgets             1.6.4     2023-12-06 [1] CRAN (R 4.5.2)
 httpuv                  1.6.17    2026-03-18 [1] CRAN (R 4.5.2)
 jquerylib               0.1.4     2021-04-26 [1] CRAN (R 4.5.2)
 jsonlite                2.0.0     2025-03-27 [1] CRAN (R 4.5.2)
 knitr                   1.51      2025-12-20 [1] CRAN (R 4.5.2)
 later                   1.4.8     2026-03-05 [1] CRAN (R 4.5.2)
 lattice                 0.22-9    2026-02-09 [2] CRAN (R 4.5.2)
 lifecycle               1.0.5     2026-01-08 [1] CRAN (R 4.5.2)
 logger                  0.4.2     2026-05-10 [1] CRAN (R 4.5.2)
 magrittr              * 2.0.5     2026-04-04 [1] CRAN (R 4.5.2)
 Matrix                  1.7-5     2026-03-21 [1] CRAN (R 4.5.2)
 memoise                 2.0.1     2021-11-26 [1] CRAN (R 4.5.2)
 mime                    0.13      2025-03-17 [1] CRAN (R 4.5.2)
 nestcolor               0.1.3     2025-01-21 [1] CRAN (R 4.5.2)
 otel                    0.2.0     2025-08-29 [1] CRAN (R 4.5.2)
 pillar                  1.11.1    2025-09-17 [1] CRAN (R 4.5.2)
 pkgcache                2.2.5     2026-04-09 [1] CRAN (R 4.5.2)
 pkgconfig               2.0.3     2019-09-22 [1] CRAN (R 4.5.2)
 processx                3.9.0     2026-04-22 [1] CRAN (R 4.5.2)
 promises                1.5.0     2025-11-01 [1] CRAN (R 4.5.2)
 ps                      1.9.3     2026-04-20 [1] CRAN (R 4.5.2)
 purrr                   1.2.2     2026-04-10 [1] CRAN (R 4.5.2)
 R6                      2.6.1     2025-02-15 [1] CRAN (R 4.5.2)
 ragg                    1.5.2     2026-03-23 [1] CRAN (R 4.5.2)
 random.cdisc.data       0.3.16    2024-10-10 [1] CRAN (R 4.5.2)
 rbibutils               2.4.1     2026-01-21 [1] CRAN (R 4.5.2)
 RColorBrewer            1.1-3     2022-04-03 [1] CRAN (R 4.5.2)
 Rcpp                    1.1.1-1.1 2026-04-24 [1] CRAN (R 4.5.2)
 Rdpack                  2.6.6     2026-02-08 [1] CRAN (R 4.5.2)
 rlang                   1.2.0     2026-04-06 [1] CRAN (R 4.5.2)
 rmarkdown               2.31      2026-03-26 [1] CRAN (R 4.5.2)
 rtables               * 0.6.16    2026-04-22 [1] CRAN (R 4.5.2)
 S7                      0.2.2     2026-04-22 [1] CRAN (R 4.5.2)
 sass                    0.4.10    2025-04-11 [1] CRAN (R 4.5.2)
 scales                  1.4.0     2025-04-24 [1] CRAN (R 4.5.2)
 sessioninfo             1.2.4     2026-06-04 [1] CRAN (R 4.5.2)
 shiny                 * 1.13.0    2026-02-20 [1] CRAN (R 4.5.2)
 shinycssloaders         1.1.0     2024-07-30 [1] CRAN (R 4.5.2)
 shinyjs                 2.1.1     2026-01-15 [1] CRAN (R 4.5.2)
 shinyvalidate           0.1.3     2023-10-04 [1] CRAN (R 4.5.2)
 shinyWidgets            0.9.1     2026-03-09 [1] CRAN (R 4.5.2)
 stringi                 1.8.7     2025-03-27 [1] CRAN (R 4.5.2)
 stringr                 1.6.0     2025-11-04 [1] CRAN (R 4.5.2)
 survival                3.8-6     2026-01-16 [2] CRAN (R 4.5.2)
 systemfonts             1.3.2     2026-03-05 [1] CRAN (R 4.5.2)
 teal                  * 1.1.0     2025-11-17 [1] CRAN (R 4.5.2)
 teal.code             * 0.7.1     2026-01-20 [1] CRAN (R 4.5.2)
 teal.data             * 0.8.0     2025-08-19 [1] CRAN (R 4.5.2)
 teal.logger             0.4.1     2025-12-02 [1] CRAN (R 4.5.2)
 teal.modules.clinical * 0.12.0    2025-12-04 [1] CRAN (R 4.5.2)
 teal.reporter           0.6.1     2026-02-20 [1] CRAN (R 4.5.2)
 teal.slice            * 0.8.0     2026-06-04 [1] CRAN (R 4.5.2)
 teal.transform        * 0.7.1     2025-12-03 [1] CRAN (R 4.5.2)
 teal.widgets            0.6.0     2026-02-24 [1] CRAN (R 4.5.2)
 tern                  * 0.9.10    2025-12-18 [1] CRAN (R 4.5.2)
 testthat                3.3.2     2026-01-11 [1] CRAN (R 4.5.2)
 textshaping             1.0.5     2026-03-06 [1] CRAN (R 4.5.2)
 tibble                  3.3.1     2026-01-11 [1] CRAN (R 4.5.2)
 tidyr                   1.3.2     2025-12-19 [1] CRAN (R 4.5.2)
 tidyselect              1.2.1     2024-03-11 [1] CRAN (R 4.5.2)
 vctrs                   0.7.3     2026-04-11 [1] CRAN (R 4.5.2)
 webshot                 0.5.5     2023-06-26 [1] CRAN (R 4.5.2)
 webshot2                0.1.2     2025-04-23 [1] CRAN (R 4.5.2)
 websocket               1.4.4     2025-04-10 [1] CRAN (R 4.5.2)
 withr                   3.0.2     2024-10-28 [1] CRAN (R 4.5.2)
 xfun                    0.58      2026-06-01 [1] CRAN (R 4.5.2)
 xtable                  1.8-8     2026-02-22 [1] CRAN (R 4.5.2)
 yaml                    2.3.12    2025-12-10 [1] CRAN (R 4.5.2)

 [1] /usr/local/lib/R/site-library
 [2] /usr/local/lib/R/library
 [3] /github/home/R/x86_64-pc-linux-gnu-library/4.5
 * ── Packages attached to the search path.

──────────────────────────────────────────────────────────────────────────────

.lock file

Download the .lock file and use renv::restore() on it to recreate environment used to generate this website.

Download

LBT13
LBT15
Source Code
---
title: LBT14
subtitle: Laboratory Test Results Shift Table -- Highest NCI CTCAE Grade Post-Baseline by Baseline NCI CTCAE Grade
---

------------------------------------------------------------------------

{{< include ../../_utils/envir_hook.qmd >}}

```{r setup, echo = FALSE, warning = FALSE, message = FALSE}
library(dplyr)
library(tern)

adsl <- random.cdisc.data::cadsl
adlb <- random.cdisc.data::cadlb

adsl <- df_explicit_na(adsl)
adlb <- df_explicit_na(adlb)

# Please note that in real clinical data, population flag like SAFFL, and parameter category like PARCAT2 needs to be
# selected properly.
adsl_f <- adsl %>% filter(SAFFL == "Y")
adlb <- adlb %>% filter(SAFFL == "Y")
```

```{r include = FALSE}
webr_code_labels <- c("setup")
```

{{< include ../../_utils/webr_no_include.qmd >}}

## Output

:::::::: panel-tabset
## Standard Table (High)

Note that the worst laboratory flag (below `WGRHIFL`) must be selected appropriately in the pre-processing step. New grouping variables `ATOXGR_GP` (post-baseline) and `BTOXGR_GP` (baseline) are created to display the correct output.

::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview

```{r variant1, test = list(result_v1 = "result")}
adlb_f <- adlb %>% filter(WGRHIFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRHIFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      ATOXGR == 1 ~ "1",
      ATOXGR == 2 ~ "2",
      ATOXGR == 3 ~ "3",
      ATOXGR == 4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      BTOXGR == 1 ~ "1",
      BTOXGR == 2 ~ "2",
      BTOXGR == 3 ~ "3",
      BTOXGR == 4 ~ "4",
      BTOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f) %>%
  prune_table()

result
```

```{r include = FALSE}
webr_code_labels <- c("variant1")
```

{{< include ../../_utils/webr.qmd >}}
:::

## Standard Table (Low)

Note that the worst laboratory flag (below `WGRLOFL`) must be selected appropriately in the pre-processing step. New grouping variables `ATOXGR_GP` (post-baseline) and `BTOXGR_GP` (baseline) are created to display the correct output.

::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview

```{r variant2, test = list(result_v2 = "result")}
adlb_f <- adlb %>% filter(WGRLOFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRLOFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, 1, 2, 3, 4) ~ "Not Low",
      ATOXGR == -1 ~ "1",
      ATOXGR == -2 ~ "2",
      ATOXGR == -3 ~ "3",
      ATOXGR == -4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not Low", "1", "2", "3", "4", "Missing"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, 1, 2, 3, 4) ~ "Not Low",
      BTOXGR == -1 ~ "1",
      BTOXGR == -2 ~ "2",
      BTOXGR == -3 ~ "3",
      BTOXGR == -4 ~ "4",
      BTOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not Low", "1", "2", "3", "4", "Missing"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f) %>%
  prune_table()

result
```

```{r include = FALSE}
webr_code_labels <- c("variant2")
```

{{< include ../../_utils/webr.qmd >}}
:::

## Table Without Patients with <br/> Missing Baseline (High)

Note that missing baseline values are filtered out in the pre-processing step.

::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview

```{r variant3, test = list(result_v3 = "result")}
adlb_f <- adlb %>% filter(WGRHIFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRHIFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  filter(BTOXGR != "<Missing>") %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      ATOXGR == 1 ~ "1",
      ATOXGR == 2 ~ "2",
      ATOXGR == 3 ~ "3",
      ATOXGR == 4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      BTOXGR == 1 ~ "1",
      BTOXGR == 2 ~ "2",
      BTOXGR == 3 ~ "3",
      BTOXGR == 4 ~ "4"
    ), levels = c("Not High", "1", "2", "3", "4"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f) %>%
  prune_table()

result
```

```{r include = FALSE}
webr_code_labels <- c("variant3")
```

{{< include ../../_utils/webr.qmd >}}
:::

## Table with Missing Baseline <br/> Considered as Grade 0 (Low)

Note that when BTOXGR is missing, the grouping variable `BTOXGR_GP` now is `"Not Low"` instead of `"Missing"` compared to *Standard Table (Low)*.

::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview

```{r variant4, test = list(result_v4 = "result")}
adlb_f <- adlb %>% filter(WGRLOFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRLOFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, 1, 2, 3, 4) ~ "Not Low",
      ATOXGR == -1 ~ "1",
      ATOXGR == -2 ~ "2",
      ATOXGR == -3 ~ "3",
      ATOXGR == -4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not Low", "1", "2", "3", "4"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, 1, 2, 3, 4, "<Missing>") ~ "Not Low",
      BTOXGR == -1 ~ "1",
      BTOXGR == -2 ~ "2",
      BTOXGR == -3 ~ "3",
      BTOXGR == -4 ~ "4"
    ), levels = c("Not Low", "1", "2", "3", "4", "Missing"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f) %>%
  prune_table()

result
```

```{r include = FALSE}
webr_code_labels <- c("variant4")
```

{{< include ../../_utils/webr.qmd >}}
:::

## Table with Fill-In of Grades

Pre-processing is the same as *Standard Table (High)*, but in order to keep all levels, `prune_table()` is not applied.

::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview

```{r variant5, test = list(result_v5 = "result")}
adlb_f <- adlb %>% filter(WGRHIFL == "Y")

# Please note the step below can be skipped if you are using DTYPE PHANTOM
adlb_out <- h_adsl_adlb_merge_using_worst_flag(adsl_f, adlb_f, worst_flag = c("WGRHIFL" = "Y"))

# Create new grouping variables ATOXGR_GP, BTOXGR_GP
adlb_out <- adlb_out %>%
  mutate(
    ATOXGR_GP = factor(case_when(
      ATOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      ATOXGR == 1 ~ "1",
      ATOXGR == 2 ~ "2",
      ATOXGR == 3 ~ "3",
      ATOXGR == 4 ~ "4",
      ATOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  ) %>%
  mutate(
    BTOXGR_GP = factor(case_when(
      BTOXGR %in% c(0, -1, -2, -3, -4) ~ "Not High",
      BTOXGR == 1 ~ "1",
      BTOXGR == 2 ~ "2",
      BTOXGR == 3 ~ "3",
      BTOXGR == 4 ~ "4",
      BTOXGR == "<Missing>" ~ "Missing"
    ), levels = c("Not High", "1", "2", "3", "4", "Missing"))
  )

result <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "PARAM",
    split_fun = drop_split_levels,
    label_pos = "topleft",
    split_label = "Parameter"
  ) %>%
  split_rows_by(
    "BTOXGR_GP",
    label_pos = "topleft",
    split_label = "    Baseline NCI-CTCAE Grade",
    indent_mod = 2L
  ) %>%
  summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>%
  count_occurrences_by_grade("ATOXGR_GP", denom = "n", drop = FALSE, .indent_mods = 3L) %>%
  append_topleft("              Post-baseline NCI-CTCAE Grade") %>%
  build_table(df = adlb_out, alt_counts_df = adsl_f)

result
```

```{r include = FALSE}
webr_code_labels <- c("variant5")
```

{{< include ../../_utils/webr.qmd >}}
:::

## Data Setup

Please note that for each variant, the `adlb` dataset needs to be filtered on correct flags like `WGRLOFL`, `WGRHIFL`, et al., otherwise the layout function will not return the correct counts. There is an option to create a record for a lab test where no record is found at that visit. If you specified `add_derived_type = "PHANTOM"` & `dtype_phantom_cond`, you don't have to use the `h_adsl_adlb_merge_using_worst_flag` function to preprocess your `adlb` dataset. Otherwise please follow the pre-processing steps below before applying the layout functions.

```{r setup}
#| code-fold: show
```
::::::::

{{< include ../../_utils/save_results.qmd >}}

## `teal` App

::: {.panel-tabset .nav-justified}
## {{< fa regular file-lines fa-sm fa-fw >}} Preview

```{r teal, opts.label = c("skip_if_testing", "app")}
library(teal.modules.clinical)

## Data reproducible code
data <- teal_data()
data <- within(data, {
  ADSL <- random.cdisc.data::cadsl
  ADLB <- random.cdisc.data::cadlb
})
join_keys(data) <- default_cdisc_join_keys[c("ADSL", "ADLB")]

## Reusable Configuration For Modules
ADSL <- data[["ADSL"]]
ADLB <- data[["ADLB"]]

## Setup App
app <- init(
  data = data,
  modules = modules(
    tm_t_shift_by_grade(
      label = "Grade Laboratory Abnormality Table",
      dataname = "ADLB",
      arm_var = choices_selected(
        choices = variable_choices(ADSL, subset = c("ARM", "ARMCD")),
        selected = "ARM"
      ),
      paramcd = choices_selected(
        choices = value_choices(ADLB, "PARAMCD", "PARAM"),
        selected = "ALT"
      ),
      worst_flag_var = choices_selected(
        choices = variable_choices(ADLB, subset = c("WGRLOVFL", "WGRLOFL", "WGRHIVFL", "WGRHIFL")),
        selected = c("WGRHIFL")
      ),
      worst_flag_indicator = choices_selected(
        value_choices(ADLB, "WGRLOVFL"),
        selected = "Y", fixed = TRUE
      ),
      anl_toxgrade_var = choices_selected(
        choices = variable_choices(ADLB, subset = c("ATOXGR")),
        selected = c("ATOXGR"),
        fixed = TRUE
      ),
      base_toxgrade_var = choices_selected(
        choices = variable_choices(ADLB, subset = c("BTOXGR")),
        selected = c("BTOXGR"),
        fixed = TRUE
      ),
      add_total = FALSE
    )
  ),
  filter = teal_slices(teal_slice("ADSL", "SAFFL", selected = "Y"))
)

shinyApp(app$ui, app$server)
```

{{< include ../../_utils/shinylive.qmd >}}
:::

{{< include ../../repro.qmd >}}

Made with ❤️ by the NEST Team

  • Edit this page
  • Report an issue
Cookie Preferences