From aa7bf40dbec3c4ae4c633d4b7423e1a25720bf5a Mon Sep 17 00:00:00 2001 From: Stefan Bundfuss Date: Mon, 25 Nov 2024 11:54:40 +0000 Subject: [PATCH] update GCIG vignette --- 294_gcig_vignette/articles/adrs_gcig.html | 315 ++++++++++++---------- 1 file changed, 173 insertions(+), 142 deletions(-) diff --git a/294_gcig_vignette/articles/adrs_gcig.html b/294_gcig_vignette/articles/adrs_gcig.html index b932b13c..f8fa048b 100644 --- a/294_gcig_vignette/articles/adrs_gcig.html +++ b/294_gcig_vignette/articles/adrs_gcig.html @@ -93,10 +93,9 @@

This article describes creating an ADRS ADaM dataset in ovarian cancer studies based on Gynecological Cancer Intergroup (GCIG) -criteria. Note that only the sections required for this vignette are -covered in the following steps. To get a detailed guidance on all the -steps, refer the Creating ADRS (Including -Non-standard Endpoints).

+criteria. Note that only the GCIG specific steps are covered in this +vignette. To get a detailed guidance on all the steps, refer the Creating ADRS (Including Non-standard +Endpoints).

Introduction

@@ -582,46 +581,47 @@

IntroductionDefinitions for -response and progression in ovarian cancer clinical trials incorporating -RECIST 1.1 and CA-125 agreed by the Gynecological Cancer Intergroup -(GCIG)

+

We aim to share our current knowledge and experience in implementing +GCIG criteria for ovarian clinical trials. Additionally, we have made +certain assumptions regarding how data is collected on CRFs to perform +response analysis according to the GCIG criteria. We hope this vignette +provides valuable guidance on ADRS programming and highlights key +considerations for data collection in relation to these criteria.

+

For more information about GCIG criteria user may visit GCIG guidelines on +response criteria in ovarian cancer

CA-125 response categories

-

The CA-125 response categories for ovarian cancer are:

+

In further considerations, ULRR stands for Upper Limit of Reference +Range. The CA-125 response categories for ovarian cancer are:

  1. CA-125 Complete Response: baseline CA-125 >= -2 * ULRR, later reduced by 50% to normal confirmed at least 4 weeks -later.

  2. -
  3. CA-125 Partial Response: baseline CA-125 CA-125 ->= 2 * ULRR, later reduced by 50% but not to normal confirmed at +2 * ULRR, later reduced by at least 50% to normal confirmed at least 4 +weeks later.

  4. +
  5. CA-125 Partial Response: baseline CA-125 >= 2 +* ULRR, later reduced by at least 50% but not to normal confirmed at least 4 weeks later.

  6. Stable Disease: CA-125 level does not meet the criteria for either partial response or progression disease.

  7. -
  8. Progression:

  9. -
+
  • +

    Progression: This is defined as CA-125 >= 2 * +ULRR or CA-125 >= 2 * nadir on 2 occasions at least 1 week apart.

      -
    • category A: CA-125 increased at baseline returning to normal +
    • category A: CA-125 elevated at baseline returning to normal after treatment: CA-125 >= 2 * ULRR on 2 occasions at least 1 week apart.
    • -
    • category B: CA-125 increased at baseline not returning to +
    • category B: CA-125 elevated at baseline not returning to normal after treatment: CA-125 >= 2 * nadir value (lowest level reached by CA-125) on 2 occasions at least 1 week apart.
    • category C: CA-125 within reference range at baseline: CA-125 >= 2 * ULRR on 2 occasions at least 1 week apart.
    -
      -
    1. -Not Evaluable: This is when the patient’s response -cannot be evaluated due to various reasons such as receiving mouse -antibodies or having medical/surgical interference with their peritoneum -or pleura during the previous 28 days.
    2. + +
    3. Not Evaluable: This is when the patient’s +response cannot be evaluated due to various reasons such as receiving +mouse antibodies or having medical/surgical interference with their +peritoneum or pleura during the previous 28 days.

  • @@ -653,6 +653,8 @@

    May be Collected:

    Assumptions:

    +

    For this vignette we made assumptions that following information is +collected on the CRF:

    1. CA-125 confirmed responses are collected on the CRF and mapped to SDTM RS domain. Please note that we are not @@ -703,49 +705,77 @@

      Assumptions: - - - + + + + + QNAM QLABEL +QVAL Purpose +Use case -CA125EFL +CA125EFL CA-125 response evaluable -CA-125 > 2x ULRR and no mouse antibodies at -baseline +Y/N +Indicates population evaluable for CA-125 response +(baseline CA-125 >= 2 * ULRR and no mouse antibodies) + +CA125EFL variable -CA2XULRR +CA2XULRR CA-125 pre-treatment 2x ULRR -CA-125 level at baseline (in range/elevated) +Y/N +Indicates CA-125 level at baseline (Y - elevated, N - +not elevated) +Derivation of PD category +(MCRIT1/MCRIT1ML/MCRIT1MN) -MOUSEANT +MOUSEANT Received mouse antibodies -Prohibited therapy +Y/N +Indicates if a prohibited therapy was received +Derivation of ANL02FL + -CA50RED +CA50RED >50% reduction from baseline -Response indicator +Y/N +Indicates response, but does not distinguish between CR +and PR +Not used in further derivations -CANORM2X +CANORM2X CA125 normal, lab increased >=2x ULRR -PD category A or C +Y/N +Indicates PD category A or C +Derivation of PD category +(MCRIT1/MCRIT1ML/MCRIT1MN) -CNOTNORM +CNOTNORM CA125 not norm, lab increased >=2x nadir -PD category B +Y/N +Indicates PD category B +Derivation of PD category +(MCRIT1/MCRIT1ML/MCRIT1MN) +

      If the data are collected by other ways and similar information from +SUPPRS dataset are not available, they should be derived in +advance from LB CA-125 measurements records. Information on +whether the patient has received mouse antibodies should also be taken +into account.

    @@ -827,23 +857,23 @@

    Select O
     param_lookup <- tribble(
       ~RSCAT, ~RSTESTCD, ~RSEVAL,
    -  ~PARAMCD, ~PARAM, ~PARAMN, 
    -  ~PARCAT1, ~PARCAT1N,~PARCAT2, ~PARCAT2N,
    -  
    -  #CA-125
    +  ~PARAMCD, ~PARAM, ~PARAMN,
    +  ~PARCAT1, ~PARCAT1N, ~PARCAT2, ~PARCAT2N,
    +
    +  # CA-125
       "CA125", "OVRLRESP", "INVESTIGATOR",
       "OVRCA125", "CA-125 Overall Response by Investigator", 1,
    -  "Investigator", 1, "CA-125", 1,
    -  
    -  #RECIST 1.1
    +  "CA-125", 1, "Investigator", 1,
    +
    +  # RECIST 1.1
       "RECIST 1.1", "OVRLRESP", "INVESTIGATOR",
       "OVRR11", "RECIST 1.1 Overall Response by Investigator", 2,
    -  "Investigator", 1, "RECIST 1.1", 2,
    -  
    -  #Combined
    +  "RECIST 1.1", 2, "Investigator", 1,
    +
    +  # Combined
       "RECIST 1.1 - CA125", "OVRLRESP", "INVESTIGATOR",
       "OVRR11CA", "Combined Overall Response by Investigator", 3,
    -  "Investigator", 1, "Combined", 3
    +  "Combined", 3, "Investigator", 1
     )

    This lookup may now be joined to the source data and this is how the parameters will look like:

    @@ -853,10 +883,10 @@

    Select O dataset_add = param_lookup, new_vars = exprs(PARAMCD, PARAM, PARAMN, PARCAT1, PARCAT1N, PARCAT2, PARCAT2N), by_vars = exprs(RSCAT, RSTESTCD, RSEVAL) -) %>% +) %>% arrange(!!!get_admiral_option("subject_keys"), PARAMN, RSSEQ)

    - +

    Partial Date Imputation and Deriving ADT, @@ -887,7 +917,7 @@

    Partial Date ) %>% mutate(AVISIT = VISIT)

    - +

    Derive AVALC and AVAL @@ -904,7 +934,7 @@

    Derive AVALC and AVAL AVAL = aval_resp(AVALC) )

    - +
    @@ -988,8 +1018,8 @@

    CA-125 Response Evaluable Flag
     adrs <- adrs %>%
       rename(CA125EFL_ = CA125EFL)
    -  
    - adrs <- adrs %>% 
    +
    +adrs <- adrs %>%
       derive_var_merged_exist_flag(
         dataset_add = adrs,
         by_vars = get_admiral_option("subject_keys"),
    @@ -997,7 +1027,7 @@ 

    CA-125 Response Evaluable Flag= (CA125EFL_ == "Y") )

    - +

    Select Source Assessments for Parameter Derivations @@ -1012,16 +1042,16 @@

    Select Source Asses progression),
    -#used for derivation of CA-125 PD
    +# used for derivation of CA-125 PD
     ovr_pd <- filter(adrs, PARAMCD == "OVRCA125" & ANL01FL == "Y" & ANL02FL == "Y")
     
    -#used for derivation of CA-125 response parameters
    +# used for derivation of CA-125 response parameters
     ovr_ca125 <- filter(adrs, PARAMCD == "OVRCA125" & CA125EFL == "Y" & ANL01FL == "Y" & ANL02FL == "Y")
     
    -#used for derivation of unconfirmed best overall response from RECIST1.1 and confirmed CA-125 together
    +# used for derivation of unconfirmed best overall response from RECIST1.1 and confirmed CA-125 together
     ovr_ubor <- filter(adrs, PARAMCD == "OVRR11CA" & CA125EFL == "Y" & ANL01FL == "Y" & ANL02FL == "Y")
     
    -#used for derivation of confirmed best overall response from RECIST1.1 and confirmed CA-125 together
    +# used for derivation of confirmed best overall response from RECIST1.1 and confirmed CA-125 together
     ovr_r11 <- filter(adrs, PARAMCD == "OVRR11" & CA125EFL == "Y" & ANL01FL == "Y" & ANL02FL == "Y")

    Now that we have the input records prepared above with any company-specific requirements, we can start to derive new parameter @@ -1047,17 +1077,17 @@

    CA-125 Progression= "PDCA125", PARAM = "CA-125 Disease Progression by Investigator", PARAMN = 4, - PARCAT1 = "Investigator", + PARCAT1 = "CA-125", PARCAT1N = 1, - PARCAT2 = "CA-125", + PARCAT2 = "Investigator", PARCAT2N = 1, ANL01FL = "Y", ANL02FL = "Y" ) - ) %>% + ) %>% arrange(!!!get_admiral_option("subject_keys"), PARAMN, ADT)

    - +

    CA-125 Progression Category @@ -1078,13 +1108,13 @@

    CA-125 Progression Category
     definition_mcrit <- exprs(
    -  ~PARAMCD, ~condition, 
    +  ~PARAMCD, ~condition,
       ~MCRIT1ML, ~MCRIT1MN,
    -  "PDCA125", CA2XULRR == "Y" & CANORM2X == "Y", 
    +  "PDCA125", CA2XULRR == "Y" & CANORM2X == "Y",
       "Patients with elevated CA-125 before treatment and normalization of CA-125 (A)", 1,
    -  "PDCA125", CA2XULRR == "Y" & CNOTNORM == "Y", 
    +  "PDCA125", CA2XULRR == "Y" & CNOTNORM == "Y",
       "Patients with elevated CA-125 before treatment, which never normalizes (B)", 2,
    -  "PDCA125", CA2XULRR == "N" & CANORM2X == "Y", 
    +  "PDCA125", CA2XULRR == "N" & CANORM2X == "Y",
       "Patients with CA-125 in the reference range before treatment (C)", 3
     )
     
    @@ -1095,7 +1125,7 @@ 

    CA-125 Progression Category= exprs(PARAMCD) )

    -

    Derivation of the progression category may be more complex if the +

    Derivation of the progression category may be more complex if the data is collected in a different way and the user needs to check whether:

      @@ -1152,9 +1182,9 @@

      CA-125 Best Confirmed Overall Response PARAMCD = "CBORCA", PARAM = "CA-125 Best Confirmed Overall Response by Investigator", PARAMN = 5, - PARCAT1 = "Investigator", + PARCAT1 = "CA-125", PARCAT1N = 1, - PARCAT2 = "CA-125", + PARCAT2 = "Investigator", PARCAT2N = 1, AVAL = aval_resp(AVALC), ANL01FL = "Y", @@ -1162,7 +1192,7 @@

      CA-125 Best Confirmed Overall Response ) )
      - +
      - +

      Confirmed RECIST 1.1 Overall Response @@ -1279,28 +1309,28 @@

      Confirmed RECIST 1.1 Overall Responseconfirmation_period <- 21 covr_r11 <- ovr_r11 %>% - arrange(USUBJID, ADTM) %>% - group_by(USUBJID) %>% - mutate( - AVALC.next = lead(AVALC), - AVAL.next = lead(AVAL), - ADT.next = lead(ADT) - ) %>% - ungroup() %>% - mutate(AVALC.confirmed = case_when( - # CR - AVALC == "CR" & AVALC.next == "CR" ~ "CR", - AVALC == "CR" & AVALC.next %in% c("PR", "SD", "PD") ~ "PD", - AVALC == "CR" & AVALC.next == "NE" ~ "NE", - # PR - AVALC == "PR" & AVALC.next %in% c("CR", "PR") ~ "PR", - AVALC == "PR" & AVALC.next %in% c("SD", "PD", "NE") ~ AVALC.next, - # next assessment NA - AVALC %in% c("CR", "PR") & is.na(AVALC.next) ~ "SD", - # no need to confirm SD, PD, NE - AVALC %in% c("SD", "PD", "NE") ~ AVALC, - !is.na(AVALC) ~ AVALC - )) + arrange(USUBJID, ADTM) %>% + group_by(USUBJID) %>% + mutate( + AVALC.next = lead(AVALC), + AVAL.next = lead(AVAL), + ADT.next = lead(ADT) + ) %>% + ungroup() %>% + mutate(AVALC.confirmed = case_when( + # CR + AVALC == "CR" & AVALC.next == "CR" ~ "CR", + AVALC == "CR" & AVALC.next %in% c("PR", "SD", "PD") ~ "PD", + AVALC == "CR" & AVALC.next == "NE" ~ "NE", + # PR + AVALC == "PR" & AVALC.next %in% c("CR", "PR") ~ "PR", + AVALC == "PR" & AVALC.next %in% c("SD", "PD", "NE") ~ AVALC.next, + # next assessment NA + AVALC %in% c("CR", "PR") & is.na(AVALC.next) ~ "SD", + # no need to confirm SD, PD, NE + AVALC %in% c("SD", "PD", "NE") ~ AVALC, + !is.na(AVALC) ~ AVALC + )) covr_r11_check <- covr_r11 %>% mutate(diff_days = as.numeric(difftime(ADT.next, ADT, units = "days"))) %>% @@ -1308,7 +1338,8 @@

      Confirmed RECIST 1.1 Overall Response mutate(warn = paste( "For USUBJID", USUBJID, "to confirm", AVISIT, "visit, a visit that took place", diff_days, "days later was used." -)) %>% pull(warn) + )) %>% + pull(warn) if (length(covr_r11_check) > 0) { cli::cli_warn("{covr_r11_check}") @@ -1324,15 +1355,15 @@

      Confirmed RECIST 1.1 Overall Response PARAMCD = "COVRR11", PARAM = "Confirmed RECIST 1.1 Overall Response by Investigator", PARAMN = 7, - PARCAT1 = "Investigator", - PARCAT1N = 1, - PARCAT2 = "RECIST 1.1", - PARCAT2N = 2, -) - + PARCAT1 = "RECIST 1.1", + PARCAT1N = 2, + PARCAT2 = "Investigator", + PARCAT2N = 1, + ) + adrs <- bind_rows(adrs, covr_r11)

      - +

      Combined Best Confirmed Overall Response @@ -1429,43 +1460,43 @@

      Combined Best Confirmed Overall Response by_vars = exprs(!!!get_admiral_option("subject_keys"), AVISIT, ADT, ANL01FL, ANL02FL), key_var = PARAMCD, value_var = AVALC - ) %>% + ) %>% select(-AVAL) %>% rename(OVRR11 = AVALC) %>% mutate(AVALC = case_when( - # CR - OVRR11 == "CR" & OVRCA125 == "CR" ~ "CR", - OVRR11 == "CR" & OVRCA125 %in% c("PR", "SD", "NE") ~ "PR", - OVRCA125 == "CR" & OVRR11 %in% c("PR", "SD", "NE") ~ "PR", - # PR - OVRR11 == "PR" & OVRCA125 %in% c("CR", "PR", "SD", "NE") ~ "PR", - OVRCA125 == "PR" & OVRR11 %in% c("CR", "PR", "SD", "NE") ~ "PR", - # SD, NE - OVRR11 %in% c("SD", "NE") & OVRCA125 %in% c("SD", "NE") & OVRR11 == OVRCA125 ~ OVRR11, - OVRR11 %in% c("SD", "NE") & OVRCA125 %in% c("SD", "NE") & OVRR11 != OVRCA125 ~ "SD", - # PD - OVRR11 == "PD" | OVRCA125 == "PD" ~ "PD", - # next assessment NA - is.na(OVRR11) | is.na(OVRCA125) ~ "NE", - TRUE ~ "MISSING" - )) + # CR + OVRR11 == "CR" & OVRCA125 == "CR" ~ "CR", + OVRR11 == "CR" & OVRCA125 %in% c("PR", "SD", "NE") ~ "PR", + OVRCA125 == "CR" & OVRR11 %in% c("PR", "SD", "NE") ~ "PR", + # PR + OVRR11 == "PR" & OVRCA125 %in% c("CR", "PR", "SD", "NE") ~ "PR", + OVRCA125 == "PR" & OVRR11 %in% c("CR", "PR", "SD", "NE") ~ "PR", + # SD, NE + OVRR11 %in% c("SD", "NE") & OVRCA125 %in% c("SD", "NE") & OVRR11 == OVRCA125 ~ OVRR11, + OVRR11 %in% c("SD", "NE") & OVRCA125 %in% c("SD", "NE") & OVRR11 != OVRCA125 ~ "SD", + # PD + OVRR11 == "PD" | OVRCA125 == "PD" ~ "PD", + # next assessment NA + is.na(OVRR11) | is.na(OVRCA125) ~ "NE", + TRUE ~ "MISSING" + )) ovr_cbor <- ovr_cbor %>% - #select(-OVRR11, -OVRCA125) %>% + # select(-OVRR11, -OVRCA125) %>% mutate( PARAMCD = "COVR11CA", PARAM = "Combined Overall Response by Investigator (Confirmation of RECIST1.1 Reqired)", PARAMN = 8, - PARCAT1 = "Investigator", - PARCAT1N = 1, - PARCAT2 = "Combined", - PARCAT2N = 3, + PARCAT1 = "Combined", + PARCAT1N = 3, + PARCAT2 = "Investigator", + PARCAT2N = 1, AVAL = aval_resp(AVALC) -) - + ) + adrs <- bind_rows(adrs, ovr_cbor)

      -

      Finally Combined Best Confirmed Overall Response parameter can be +

      Finally Combined Best Confirmed Overall Response parameter can be derived based on ovr_cbor data frame.

      - +

      Other Endpoints