This article describes creating an ADRS
ADaM with oncology endpoint parameters based on iRECIST. It shows a similar way of deriving the endpoints presented in Creating ADRS (Including Non-standard Endpoints). Most of the endpoints are derived by calling admiral::derive_extreme_event()
.
This vignette follows the iRECIST guidelines, for more information user may visit https://recist.eortc.org/irecist/
Examples are currently presented and tested using ADSL
(ADaM) and RS
(SDTM) inputs. However, other domains could be used. The RS
test data contains iRECIST response for target, non-target and overall response. Further pre-processing and considerations may be needed if iRECIST are only collected after RECIST 1.1 progression and input data contains multiple response criteria. The functions and workflow could similarly be used to create an intermediary ADEVENT
ADaM.
Note: All examples assume CDISC SDTM and/or ADaM format as input unless otherwise specified.
To start, all data frames needed for the creation of ADRS
should be read into the environment. This will be a company specific process. Some of the data frames needed may be ADSL
, RS
and TU
. For this vignette we assume that RS
provides the response values "iCR"
, "iPR"
, "iSD"
, "NON-iCR/NON-iUPD"
, "iUPD"
, "iCPD"
, and "NE"
. All examples can be easily modified to consider other response values (see Handling Different Input Response Values).
For example purpose, the SDTM and ADaM datasets (based on CDISC Pilot test data)—which are included in {pharmaversesdtm}
and {pharmaverseadam}
—are used.
library(admiral)
library(admiralonco)
library(dplyr)
library(pharmaverseadam)
library(pharmaversesdtm)
library(lubridate)
library(stringr)
data("adsl")
# iRECIST oncology sdtm data
data("rs_onco_irecist")
<- rs_onco_irecist
rs
<- convert_blanks_to_na(rs) rs
At this step, it may be useful to join ADSL
to your RS
domain. Only the ADSL
variables used for derivations are selected at this step. The rest of the relevant ADSL
would be added later.
<- exprs(RANDDT)
adsl_vars <- derive_vars_merged(
adrs
rs,dataset_add = adsl,
new_vars = adsl_vars,
by_vars = exprs(STUDYID, USUBJID)
)
USUBJID | RSTESTCD | RSDTC | VISIT | RANDDT |
---|---|---|---|---|
01-701-1015 | OVRLRESP | 2014-02-12 | WEEK 6 | 2014-01-02 |
01-701-1028 | OVRLRESP | 2013-08 | WEEK 6 | 2013-07-19 |
01-701-1028 | OVRLRESP | 2013-10-09 | WEEK 12 | 2013-07-19 |
01-701-1028 | OVRLRESP | 2013-11-20 | WEEK 18 | 2013-07-19 |
01-701-1034 | OVRLRESP | 2014-08-11 | WEEK 6 | 2014-07-01 |
01-701-1034 | OVRLRESP | 2014-09-25 | WEEK 12 | 2014-07-01 |
01-701-1034 | OVRLRESP | 2014-11-04 | WEEK 18 | 2014-07-01 |
01-701-1097 | OVRLRESP | 2014-02-11 | WEEK 6 | 2014-01-01 |
01-701-1115 | OVRLRESP | 2013-01-10 | WEEK 6 | 2012-11-30 |
01-701-1118 | OVRLRESP | 2014-04-23 | WEEK 6 | 2014-03-12 |
The first step involves company-specific pre-processing of records for the required input to the downstream parameter functions. Note that this could be needed multiple times (e.g. once for investigator and once for Independent Review Facility (IRF)/Blinded Independent Central Review (BICR) records). It could even involve merging input data from other sources besides RS
, such as ADTR
.
This step would include any required selection/derivation of ADT
or applying any necessary partial date imputations, updating AVAL
(e.g. this should be ordered from best to worst response), and setting analysis flag ANL01FL
. Common options for ANL01FL
would be to set null for invalid assessments or those occurring after new anti-cancer therapy, or to only flag assessments on or after date of first treatment/randomization, or rules to cover the case when a patient has multiple observations per visit (e.g. by selecting the worst value). Another consideration could be extra potential protocol-specific sources of Progressive Disease such as radiological assessments, which could be pre-processed here to create a PD record to feed downstream derivations.
For the derivation of the parameters it is expected that the subject identifier variables (usually STUDYID
and USUBJID
) and ADT
are a unique key. This can be achieved by deriving an analysis flag (ANLzzFL
). See Derive ANL01FL
for an example.
The below shows an example of a possible company-specific implementation of this step.
In this case we use the overall response records from RS
from the investigator as our starting point. The parameter details such as PARAMCD
, PARAM
etc will always be company-specific, but an example is shown below so that you can trace through how these records feed into the other parameter derivations.
<- adrs %>%
adrs filter(RSEVAL == "INVESTIGATOR" & RSTESTCD == "OVRLRESP") %>%
mutate(
PARAMCD = "OVR",
PARAM = "Overall Response by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "iRECIST"
)
USUBJID | VISIT | RSTESTCD | RSEVAL | PARAMCD | PARAM | PARCAT1 | PARCAT2 | PARCAT3 |
---|---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
01-701-1028 | WEEK 6 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
01-701-1028 | WEEK 12 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
01-701-1028 | WEEK 18 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
01-701-1034 | WEEK 6 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
01-701-1034 | WEEK 12 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
01-701-1034 | WEEK 18 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
01-701-1097 | WEEK 6 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
01-701-1115 | WEEK 6 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
01-701-1118 | WEEK 6 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | iRECIST |
ADT
, ADTF
, AVISIT
etcIf your data collection allows for partial dates, you could apply a company-specific imputation rule at this stage when deriving ADT
. For this example, here we impute missing day to last possible date.
<- adrs %>%
adrs derive_vars_dt(
dtc = RSDTC,
new_vars_prefix = "A",
highest_imputation = "D",
date_imputation = "last"
%>%
) mutate(AVISIT = VISIT)
USUBJID | AVISIT | PARAMCD | PARAM | RSSTRESC | RSDTC | ADT | ADTF |
---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2014-02-12 | 2014-02-12 | NA |
01-701-1028 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2013-08 | 2013-08-31 | D |
01-701-1028 | WEEK 12 | OVR | Overall Response by Investigator | iCPD | 2013-10-09 | 2013-10-09 | NA |
01-701-1028 | WEEK 18 | OVR | Overall Response by Investigator | iSD | 2013-11-20 | 2013-11-20 | NA |
01-701-1034 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2014-08-11 | 2014-08-11 | NA |
01-701-1034 | WEEK 12 | OVR | Overall Response by Investigator | iSD | 2014-09-25 | 2014-09-25 | NA |
01-701-1034 | WEEK 18 | OVR | Overall Response by Investigator | NON-iCR/NON-iUPD | 2014-11-04 | 2014-11-04 | NA |
01-701-1097 | WEEK 6 | OVR | Overall Response by Investigator | NE | 2014-02-11 | 2014-02-11 | NA |
01-701-1115 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2013-01-10 | 2013-01-10 | NA |
01-701-1118 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2014-04-23 | 2014-04-23 | NA |
AVALC
and AVAL
Here we populate AVALC
and create the numeric version as AVAL
(ordered from worst to best response, followed by NE
and MISSING). The AVAL
values are not considered in the parameter derivations below, and so changing AVAL
here would not change the result of those derivations. However, please note that the ordering of AVAL
will be used to determine ANL01FL
in the subsequent step, ensure that the appropriate mode
is being set in the admiral::derive_var_extreme_flag()
.
iRECIST ordering will be used or if you’d like to provide your own company-specific ordering here you could do this as follows:
<- function(arg) {
aval_resp_new case_when(
== "NE" ~ 8,
arg == "MISSING" ~ 7,
arg == "iCR" ~ 6,
arg == "iPR" ~ 5,
arg == "iSD" ~ 4,
arg == "NON-iCR/NON-iUPD" ~ 3,
arg == "iUPD" ~ 2,
arg == "iCPD" ~ 1,
arg TRUE ~ NA_real_
)
}
<- adrs %>%
adrs mutate(
AVALC = RSSTRESC,
AVAL = aval_resp_new(AVALC)
)
USUBJID | AVISIT | PARAMCD | PARAM | RSSTRESC | AVALC | AVAL |
---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | iUPD | 2 |
01-701-1028 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | iUPD | 2 |
01-701-1028 | WEEK 12 | OVR | Overall Response by Investigator | iCPD | iCPD | 1 |
01-701-1028 | WEEK 18 | OVR | Overall Response by Investigator | iSD | iSD | 4 |
01-701-1034 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | iUPD | 2 |
01-701-1034 | WEEK 12 | OVR | Overall Response by Investigator | iSD | iSD | 4 |
01-701-1034 | WEEK 18 | OVR | Overall Response by Investigator | NON-iCR/NON-iUPD | NON-iCR/NON-iUPD | 3 |
01-701-1097 | WEEK 6 | OVR | Overall Response by Investigator | NE | NE | 8 |
01-701-1115 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | iUPD | 2 |
01-701-1118 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | iUPD | 2 |
ANL01FL
)When deriving ANL01FL
this is an opportunity to exclude any records that should not contribute to any downstream parameter derivations. In the below example this includes only selecting valid assessments and those occurring on or after randomization date. If there is more than one assessment at a date, the worst one is flagged.
<- adrs %>%
adrs restrict_derivation(
derivation = derive_var_extreme_flag,
args = params(
by_vars = exprs(STUDYID, USUBJID, ADT),
order = exprs(AVAL, RSSEQ),
new_var = ANL01FL,
mode = "first"
),filter = !is.na(AVAL) & AVALC != "MISSING" & ADT >= RANDDT
)
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | RANDDT | ANL01FL |
---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2014-02-12 | 2014-01-02 | Y |
01-701-1028 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2013-08-31 | 2013-07-19 | Y |
01-701-1028 | WEEK 12 | OVR | Overall Response by Investigator | iCPD | 2013-10-09 | 2013-07-19 | Y |
01-701-1028 | WEEK 18 | OVR | Overall Response by Investigator | iSD | 2013-11-20 | 2013-07-19 | Y |
01-701-1034 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2014-08-11 | 2014-07-01 | Y |
01-701-1034 | WEEK 12 | OVR | Overall Response by Investigator | iSD | 2014-09-25 | 2014-07-01 | Y |
01-701-1034 | WEEK 18 | OVR | Overall Response by Investigator | NON-iCR/NON-iUPD | 2014-11-04 | 2014-07-01 | Y |
01-701-1097 | WEEK 6 | OVR | Overall Response by Investigator | NE | 2014-02-11 | 2014-01-01 | Y |
01-701-1115 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2013-01-10 | 2012-11-30 | Y |
01-701-1118 | WEEK 6 | OVR | Overall Response by Investigator | iUPD | 2014-04-23 | 2014-03-12 | Y |
Here is an alternative example where those records occurring after new anti-cancer therapy are additionally excluded (where NACTDT
would be pre-derived as first date of new anti-cancer therapy. See {admiralonco}
Creating and Using New Anti-Cancer Start Date for deriving this variable).
<- adrs %>%
adrs mutate(
ANL01FL = case_when(
!is.na(AVAL) & ADT >= RANDDT & ADT < NACTDT ~ "Y",
TRUE ~ NA_character_
) )
ANL02FL
)To restrict response data up to and including first reported progressive disease ANL02FL
flag could be created by using {admiral}
function admiral::derive_var_relative_flag()
.
<- adrs %>%
adrs derive_var_relative_flag(
by_vars = exprs(STUDYID, USUBJID),
order = exprs(ADT, RSSEQ),
new_var = ANL02FL,
condition = AVALC == "iCPD",
mode = "first",
selection = "before",
inclusive = TRUE
)
USUBJID | AVISIT | PARAMCD | AVALC | ADT | ANL01FL | ANL02FL |
---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | OVR | iUPD | 2014-02-12 | Y | Y |
01-701-1028 | WEEK 6 | OVR | iUPD | 2013-08-31 | Y | Y |
01-701-1028 | WEEK 12 | OVR | iCPD | 2013-10-09 | Y | Y |
01-701-1028 | WEEK 18 | OVR | iSD | 2013-11-20 | Y | NA |
01-701-1034 | WEEK 6 | OVR | iUPD | 2014-08-11 | Y | Y |
01-701-1034 | WEEK 12 | OVR | iSD | 2014-09-25 | Y | Y |
01-701-1034 | WEEK 18 | OVR | NON-iCR/NON-iUPD | 2014-11-04 | Y | Y |
01-701-1097 | WEEK 6 | OVR | NE | 2014-02-11 | Y | Y |
01-701-1115 | WEEK 6 | OVR | iUPD | 2013-01-10 | Y | Y |
01-701-1118 | WEEK 6 | OVR | iUPD | 2014-04-23 | Y | Y |
For most parameter derivations the post-baseline overall response assessments up to and including first iCPD are considered.
<- filter(adrs, PARAMCD == "OVR" & ANL01FL == "Y" & ANL02FL == "Y") ovr
USUBJID | AVISIT | AVALC | ADT | RANDDT |
---|---|---|---|---|
01-701-1015 | WEEK 6 | iUPD | 2014-02-12 | 2014-01-02 |
01-701-1028 | WEEK 6 | iUPD | 2013-08-31 | 2013-07-19 |
01-701-1028 | WEEK 12 | iCPD | 2013-10-09 | 2013-07-19 |
01-701-1034 | WEEK 6 | iUPD | 2014-08-11 | 2014-07-01 |
01-701-1034 | WEEK 12 | iSD | 2014-09-25 | 2014-07-01 |
01-701-1034 | WEEK 18 | NON-iCR/NON-iUPD | 2014-11-04 | 2014-07-01 |
01-701-1097 | WEEK 6 | NE | 2014-02-11 | 2014-01-01 |
01-701-1115 | WEEK 6 | iUPD | 2013-01-10 | 2012-11-30 |
01-701-1118 | WEEK 6 | iUPD | 2014-04-23 | 2014-03-12 |
01-701-1118 | WEEK 12 | iSD | 2014-06-05 | 2014-03-12 |
The building blocks for the events that contribute to deriving common endpoints like what constitutes a responder, or a Best Overall Response of complete response (CR), … are predefined in admiralonco for RECIST 1.1 (see Pre-Defined Response Event Objects). New Response Event Objects are needed for iRECIST and any study-specific needs.
<- event_joined(
icpd_y description = paste(
"Define confirmed progressive disease (iCPD) as",
"iUPD followed by iCPD with only other iUPD and NE responses in between"
),dataset_name = "ovr",
join_vars = exprs(AVALC, ADT),
join_type = "after",
first_cond_upper = AVALC.join == "iCPD",
condition = AVALC == "iUPD" &
all(AVALC.join %in% c("iCPD", "iUPD", "NE")),
set_values_to = exprs(AVALC = "Y")
)
<- event_joined(
iupd_y description = paste(
"Define unconfirmed progressive disease (iUPD) as",
"iUPD followed only by other iUPD or NE responses"
),dataset_name = "ovr",
join_vars = exprs(AVALC, ADT),
join_type = "all",
condition = ADT <= ADT.join & AVALC == "iUPD" & all(AVALC.join %in% c("iUPD", "NE")),
set_values_to = exprs(AVALC = "Y")
)
<- event(
no_data_n description = "Define no response for all patients in adsl (should be used as last event)",
dataset_name = "adsl",
condition = TRUE,
set_values_to = exprs(AVALC = "N"),
keep_source_vars = adsl_vars
)
<- event(
no_data_missing description = paste(
"Define missing response (MISSING) for all patients in adsl (should be used",
"as last event)"
),dataset_name = "adsl",
condition = TRUE,
set_values_to = exprs(AVALC = "MISSING"),
keep_source_vars = adsl_vars
)
If RS
contains other response values than the iRECIST responses, the event()
and event_joined()
can be adjusted to cover this scenario. For example, if RECIST responses ("CR"
, "PR"
, "SD"
, …) are collected up to first PD and iRECIST responses ("iCR"
, "iPR"
, "iSD"
, …) thereafter, the event()
object defining unconfirmed response can be adjusted in the following way.
irsp_y <- event(
description = "Define CR, iCR, PR, or iPR as (unconfirmed) response",
dataset_name = "ovr",
condition = AVALC %in% c("CR", "iCR", "PR", "iPR"),
set_values_to = exprs(AVALC = "Y")
)
Now that we have the input records prepared above with any company-specific requirements, we can start to derive new parameter records. For the parameter derivations, all values except those overwritten by set_values_to
argument are kept from the earliest occurring input record fulfilling the required criteria.
When an iCPD
occurs, the date of progression would be the first occurrence of iUPD
in that block. For example, when we have values of iUPD
, iUPD
, and iCPD
, the iRECIST PD
date would be the first occurrence of iUPD
. In cases where we have SD
, SD
, iUPD
, PR
, PR
, iUPD
, and iCPD
, the iRECIST PD
date would be the second occurrence of iUPD
.
The function admiral::derive_extreme_records()
, in conjunction with the event icpd_y
, could be used to find the date of the first iUPD
.
For the Unconfirmed Progressive Disease Parameter, it can be of interest to look at iUPD
that has never been confirmed and no subsequent iSD
, iPR
or iCR
has been observed.
<- adrs %>%
adrs derive_extreme_event(
by_vars = exprs(STUDYID, USUBJID),
order = exprs(ADT),
mode = "first",
source_datasets = list(
ovr = ovr,
adsl = adsl
),events = list(icpd_y, no_data_n),
set_values_to = exprs(
PARAMCD = "ICPD",
PARAM = "iRECIST Confirmation of Disease Progression by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "iRECIST",
AVAL = yn_to_numeric(AVALC),
ANL01FL = "Y"
)
)
<- ovr
ovr_orig <- ovr %>%
ovr group_by(USUBJID) %>%
filter(ADT >= max_cond(var = ADT, cond = AVALC == "iUPD")) %>%
ungroup(USUBJID)
<- adrs %>%
adrs derive_extreme_event(
by_vars = exprs(STUDYID, USUBJID),
order = exprs(ADT),
mode = "first",
source_datasets = list(
ovr = ovr,
adsl = adsl
),events = list(iupd_y, no_data_n),
set_values_to = exprs(
PARAMCD = "IUPD",
PARAM = "iRECIST Unconfirmed Disease Progression by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "iRECIST",
AVAL = yn_to_numeric(AVALC),
ANL01FL = "Y"
)
)<- ovr_orig ovr
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | ANL01FL |
---|---|---|---|---|---|---|
01-701-1015 | NA | ICPD | iRECIST Confirmation of Disease Progression by Investigator | N | NA | Y |
01-701-1023 | NA | ICPD | iRECIST Confirmation of Disease Progression by Investigator | N | NA | Y |
01-701-1028 | WEEK 6 | ICPD | iRECIST Confirmation of Disease Progression by Investigator | Y | 2013-08-31 | Y |
01-701-1034 | NA | ICPD | iRECIST Confirmation of Disease Progression by Investigator | N | NA | Y |
01-701-1097 | NA | ICPD | iRECIST Confirmation of Disease Progression by Investigator | N | NA | Y |
01-701-1115 | NA | ICPD | iRECIST Confirmation of Disease Progression by Investigator | N | NA | Y |
01-701-1118 | NA | ICPD | iRECIST Confirmation of Disease Progression by Investigator | N | NA | Y |
01-701-1130 | NA | ICPD | iRECIST Confirmation of Disease Progression by Investigator | N | NA | Y |
01-701-1133 | NA | ICPD | iRECIST Confirmation of Disease Progression by Investigator | N | NA | Y |
01-701-1146 | NA | ICPD | iRECIST Confirmation of Disease Progression by Investigator | N | NA | Y |
For progressive disease and response shown in steps here and below, in our examples we show these as ADRS
parameters, but they could equally be achieved via ADSL
dates or ADEVENT
parameters.If you prefer to store as an ADSL date, then the function admiral::derive_var_extreme_dt()
could be used to find the date of first iCPD
as a variable, rather than as a new parameter record.
The function admiral::derive_extreme_event()
can then be used to find the date of first response. In the below example, the response condition has been defined as iCR
or iPR
via the event irsp_y
that was created for iRECIST.
<- event(
irsp_y description = "Define iCR or iPR as (unconfirmed) response",
dataset_name = "ovr",
condition = AVALC %in% c("iCR", "iPR"),
set_values_to = exprs(AVALC = "Y")
)
<- adrs %>%
adrs derive_extreme_event(
by_vars = exprs(STUDYID, USUBJID),
order = exprs(ADT),
mode = "first",
events = list(irsp_y, no_data_n),
source_datasets = list(
ovr = ovr,
adsl = adsl
),set_values_to = exprs(
PARAMCD = "IRSP",
PARAM = "iRECIST Response by Investigator (confirmation not required)",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "iRECIST",
AVAL = yn_to_numeric(AVALC),
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | ANL01FL |
---|---|---|---|---|---|---|
01-701-1015 | NA | IRSP | iRECIST Response by Investigator (confirmation not required) | N | NA | Y |
01-701-1023 | NA | IRSP | iRECIST Response by Investigator (confirmation not required) | N | NA | Y |
01-701-1028 | NA | IRSP | iRECIST Response by Investigator (confirmation not required) | N | NA | Y |
01-701-1034 | NA | IRSP | iRECIST Response by Investigator (confirmation not required) | N | NA | Y |
01-701-1097 | NA | IRSP | iRECIST Response by Investigator (confirmation not required) | N | NA | Y |
01-701-1115 | NA | IRSP | iRECIST Response by Investigator (confirmation not required) | N | NA | Y |
01-701-1118 | NA | IRSP | iRECIST Response by Investigator (confirmation not required) | N | NA | Y |
01-701-1130 | WEEK 12 | IRSP | iRECIST Response by Investigator (confirmation not required) | Y | 2014-05-16 | Y |
01-701-1133 | WEEK 12 | IRSP | iRECIST Response by Investigator (confirmation not required) | Y | 2013-01-22 | Y |
01-701-1146 | NA | IRSP | iRECIST Response by Investigator (confirmation not required) | N | NA | Y |
The function admiral::derive_extreme_event()
can then be used to derive the clinical benefit parameter, which we define as a patient having had a response or a sustained period of time before first iUPD
. This could also be known as disease control. In this example the “sustained period” has been defined as 42 days after randomization date via the created icb_y
event.
<- event(
icb_y description = paste(
"Define iCR, iPR, iSD, or NON-iCR/NON-iUPD occuring at least 42 days after",
"randomization as clinical benefit"
),dataset_name = "ovr",
condition = AVALC %in% c("iCR", "iPR", "iSD", "NON-iCR/NON-iUPD") &
>= RANDDT + 42,
ADT set_values_to = exprs(AVALC = "Y")
)
Please note that the result AVALC = "Y"
is defined by the first two events specified for events
. For subjects with observations fulfilling both events the one with the earlier date should be selected (and not the first one in the list). Thus ignore_event_order
and tmp_event_nr_var
are not specified.
<- adrs %>%
adrs derive_extreme_event(
by_vars = exprs(STUDYID, USUBJID),
order = exprs(desc(AVALC), ADT),
mode = "first",
events = list(irsp_y, icb_y, no_data_n),
source_datasets = list(
ovr = ovr,
adsl = adsl
),set_values_to = exprs(
PARAMCD = "ICB",
PARAM = "iRECIST Clinical Benefit by Investigator (confirmation for response not required)",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "iRECIST",
AVAL = yn_to_numeric(AVALC),
ANL01FL = "Y"
),check_type = "none"
)
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | RANDDT | ANL01FL |
---|---|---|---|---|---|---|---|
01-701-1015 | NA | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | N | NA | 2014-01-02 | Y |
01-701-1023 | NA | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | N | NA | 2012-08-05 | Y |
01-701-1028 | NA | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | N | NA | 2013-07-19 | Y |
01-701-1034 | WEEK 12 | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | Y | 2014-09-25 | 2014-07-01 | Y |
01-701-1097 | NA | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | N | NA | 2014-01-01 | Y |
01-701-1115 | NA | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | N | NA | 2012-11-30 | Y |
01-701-1118 | WEEK 12 | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | Y | 2014-06-05 | 2014-03-12 | Y |
01-701-1130 | WEEK 12 | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | Y | 2014-05-16 | 2014-02-15 | Y |
01-701-1133 | WEEK 6 | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | Y | 2012-12-11 | 2012-10-28 | Y |
01-701-1146 | NA | ICB | iRECIST Clinical Benefit by Investigator (confirmation for response not required) | N | NA | 2013-05-20 | Y |
The function admiral::derive_extreme_event()
can be used to derive the best overall response (without confirmation required) parameter. Similar to the above function you can optionally decide what period would you consider an iSD
or NON-iCR/NON-iUPD
as being eligible from. In this example, 42 days after randomization date has been used again.
Please note that the order of the events specified for events
is important. For example, a subject with iPR
, iPR
, iCR
qualifies for both ibor_icr
and ibor_ipr
. As ibor_icr
is listed before ibor_ipr
, iCR
is selected as best overall response for this subject.
<- event(
ibor_icr description = "Define complete response (iCR) for best overall response (iBOR)",
dataset_name = "ovr",
condition = AVALC == "iCR",
set_values_to = exprs(AVALC = "iCR")
)
<- event(
ibor_ipr description = "Define partial response (iPR) for best overall response (iBOR)",
dataset_name = "ovr",
condition = AVALC == "iPR",
set_values_to = exprs(AVALC = "iPR")
)
<- event(
ibor_isd description = paste(
"Define stable disease (iSD) for best overall response (iBOR) as iCR, iPR, or iSD",
"occurring at least 42 days after randomization"
),dataset_name = "ovr",
condition = AVALC %in% c("iCR", "iPR", "iSD") & ADT >= RANDDT + 42,
set_values_to = exprs(AVALC = "iSD")
)
<- event(
ibor_non_icriupd description = paste(
"Define NON-iCR/NON-iUPD for best overall response (iBOR) as NON-iCR/NON-iUPD",
"occuring at least 42 days after randomization"
),dataset_name = "ovr",
condition = AVALC == "NON-iCR/NON-iUPD" & ADT >= RANDDT + 42,
set_values_to = exprs(AVALC = "NON-iCR/NON-iUPD")
)
<- event_joined(
ibor_icpd description = paste(
"Define confirmed progressive disease (iCPD) for best overall response (iBOR) as",
"iUPD followed by iCPD with only other iUPD and NE responses in between"
),dataset_name = "ovr",
join_vars = exprs(AVALC, ADT),
join_type = "after",
first_cond_upper = AVALC.join == "iCPD",
condition = AVALC == "iUPD" &
all(AVALC.join %in% c("iCPD", "iUPD", "NE")),
set_values_to = exprs(AVALC = "iCPD")
)
<- event(
ibor_iupd description = "Define unconfirmed progressive disease (iUPD) for best overall response (iBOR)",
dataset_name = "ovr",
condition = AVALC == "iUPD",
set_values_to = exprs(AVALC = "iUPD")
)
<- event(
ibor_ne description = paste(
"Define not evaluable (NE) for best overall response (iBOR) as iCR, iPR, iSD,",
"NON-iCR/NON-iUPD, or NE (should be specified after ibor_isd and ibor_non_icriupd)"
),dataset_name = "ovr",
condition = AVALC %in% c("iCR", "iPR", "iSD", "NON-iCR/NON-iUPD", "NE"),
set_values_to = exprs(AVALC = "NE")
)
<- adrs %>%
adrs derive_extreme_event(
by_vars = exprs(STUDYID, USUBJID),
tmp_event_nr_var = event_nr,
order = exprs(event_nr, ADT),
mode = "first",
source_datasets = list(
ovr = ovr,
adsl = adsl
),events = list(ibor_icr, ibor_ipr, ibor_isd, ibor_non_icriupd, ibor_icpd, ibor_iupd, ibor_ne, no_data_missing),
set_values_to = exprs(
PARAMCD = "IBOR",
PARAM = "iRECIST Best Overall Response by Investigator (confirmation not required)",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "iRECIST",
AVAL = aval_resp_new(AVALC),
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | RANDDT | ANL01FL |
---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | iUPD | 2014-02-12 | 2014-01-02 | Y |
01-701-1023 | NA | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | MISSING | NA | 2012-08-05 | Y |
01-701-1028 | WEEK 6 | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | iCPD | 2013-08-31 | 2013-07-19 | Y |
01-701-1034 | WEEK 12 | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | iSD | 2014-09-25 | 2014-07-01 | Y |
01-701-1097 | WEEK 6 | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | NE | 2014-02-11 | 2014-01-01 | Y |
01-701-1115 | WEEK 6 | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | iUPD | 2013-01-10 | 2012-11-30 | Y |
01-701-1118 | WEEK 12 | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | iSD | 2014-06-05 | 2014-03-12 | Y |
01-701-1130 | WEEK 12 | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | iCR | 2014-05-16 | 2014-02-15 | Y |
01-701-1133 | WEEK 12 | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | iPR | 2013-01-22 | 2012-10-28 | Y |
01-701-1146 | WEEK 6 | IBOR | iRECIST Best Overall Response by Investigator (confirmation not required) | iUPD | 2013-06-30 | 2013-05-20 | Y |
Any of the above response parameters can be repeated for “confirmed” responses only. For these the function admiral::derive_extreme_event()
can be used with different events. Some of the other functions from above can then be re-used passing in these confirmed response records. See the examples below of derived parameters requiring confirmation. The assessment and the confirmatory assessment here need to occur at least 28 days apart (without any +1 applied to this calculation of days between visits), using the icrsp_y_cr
, icrsp_y_ipr
, icbor_icr
, and icbor_ipr
event. Here the confirmation period and the keep_source_vars
argument is updated, as well as the first_cond_upper
and condition
for the iRECIST values.
<- 28
confirmation_period
<- event_joined(
icrsp_y_icr description = paste(
"Define confirmed response as iCR followed by iCR at least",
confirmation_period,"days later and at most one NE in between"
),dataset_name = "ovr",
join_vars = exprs(AVALC, ADT),
join_type = "after",
order = exprs(ADT),
first_cond_upper = AVALC.join == "iCR" &
>= ADT + days(confirmation_period),
ADT.join condition = AVALC == "iCR" &
all(AVALC.join %in% c("iCR", "NE")) &
count_vals(var = AVALC.join, val = "NE") <= 1,
set_values_to = exprs(AVALC = "Y")
)
<- event_joined(
icrsp_y_ipr description = paste(
"Define confirmed response as iPR followed by iCR or iPR at least",
confirmation_period,"days later at most one NE in between, and no iPR after iCR"
),dataset_name = "ovr",
join_vars = exprs(AVALC, ADT),
join_type = "after",
order = exprs(ADT),
first_cond_upper = AVALC.join %in% c("iCR", "iPR") &
>= ADT + days(confirmation_period),
ADT.join condition = AVALC == "iPR" &
all(AVALC.join %in% c("iCR", "iPR", "NE")) &
count_vals(var = AVALC.join, val = "NE") <= 1 &
(min_cond(
var = ADT.join,
cond = AVALC.join == "iCR"
> max_cond(var = ADT.join, cond = AVALC.join == "iPR") |
) count_vals(var = AVALC.join, val = "iCR") == 0 |
count_vals(var = AVALC.join, val = "iPR") == 0
),set_values_to = exprs(AVALC = "Y")
)
<- event_joined(
icbor_icr description = paste(
"Define complete response (iCR) for confirmed best overall response (iCBOR) as",
"iCR followed by iCR at least",
confirmation_period,"days later and at most one NE in between"
),dataset_name = "ovr",
join_vars = exprs(AVALC, ADT),
join_type = "after",
first_cond_upper = AVALC.join == "iCR" &
>= ADT + confirmation_period,
ADT.join condition = AVALC == "iCR" &
all(AVALC.join %in% c("iCR", "NE")) &
count_vals(var = AVALC.join, val = "NE") <= 1,
set_values_to = exprs(AVALC = "iCR")
)
<- event_joined(
icbor_ipr description = paste(
"Define partial response (iPR) for confirmed best overall response (iCBOR) as",
"iPR followed by iCR or iPR at least",
confirmation_period,"days later, at most one NE in between and no iPR after iCR"
),dataset_name = "ovr",
join_vars = exprs(AVALC, ADT),
join_type = "after",
first_cond_upper = AVALC.join %in% c("iCR", "iPR") &
>= ADT + confirmation_period,
ADT.join condition = AVALC == "iPR" &
all(AVALC.join %in% c("iCR", "iPR", "NE")) &
count_vals(var = AVALC.join, val = "NE") <= 1 &
(min_cond(
var = ADT.join,
cond = AVALC.join == "iCR"
> max_cond(var = ADT.join, cond = AVALC.join == "iPR") |
) count_vals(var = AVALC.join, val = "iCR") == 0 |
count_vals(var = AVALC.join, val = "iPR") == 0
),set_values_to = exprs(AVALC = "iPR")
)
Please note that the result AVALC = "Y"
for confirmed clinical benefit is defined by the first two events specified for events
. For subjects with observations fulfilling both events the one with the earlier date should be selected (and not the first one in the list).
<- adrs %>%
adrs derive_extreme_event(
by_vars = exprs(STUDYID, USUBJID),
order = exprs(desc(AVALC), ADT),
mode = "first",
source_datasets = list(
ovr = ovr,
adsl = adsl
),events = list(icrsp_y_icr, icrsp_y_ipr, no_data_n),
set_values_to = exprs(
PARAMCD = "ICRSP",
PARAM = "iRECIST Confirmed Response by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "iRECIST",
AVAL = yn_to_numeric(AVALC),
ANL01FL = "Y"
)
)
<- adrs %>%
adrs derive_extreme_event(
by_vars = exprs(STUDYID, USUBJID),
order = exprs(desc(AVALC), ADT),
mode = "first",
events = list(icrsp_y_icr, icrsp_y_ipr, icb_y, no_data_n),
source_datasets = list(
ovr = ovr,
adsl = adsl
),set_values_to = exprs(
PARAMCD = "ICCB",
PARAM = "iRECIST Confirmed Clinical Benefit by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "iRECIST",
AVAL = yn_to_numeric(AVALC),
ANL01FL = "Y"
),check_type = "none"
)
<- adrs %>%
adrs derive_extreme_event(
by_vars = exprs(STUDYID, USUBJID),
tmp_event_nr_var = event_nr,
order = exprs(event_nr, ADT),
mode = "first",
events = list(icbor_icr, icbor_ipr, ibor_isd, ibor_non_icriupd, ibor_icpd, ibor_iupd, ibor_ne, no_data_missing),
source_datasets = list(
ovr = ovr,
adsl = adsl
),set_values_to = exprs(
PARAMCD = "ICBOR",
PARAM = "iRECIST Best Confirmed Overall Response by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "iRECIST",
AVAL = aval_resp(AVALC),
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | RANDDT | ANL01FL |
---|---|---|---|---|---|---|---|
01-701-1015 | NA | ICRSP | iRECIST Confirmed Response by Investigator | N | NA | 2014-01-02 | Y |
01-701-1023 | NA | ICRSP | iRECIST Confirmed Response by Investigator | N | NA | 2012-08-05 | Y |
01-701-1028 | NA | ICRSP | iRECIST Confirmed Response by Investigator | N | NA | 2013-07-19 | Y |
01-701-1034 | NA | ICRSP | iRECIST Confirmed Response by Investigator | N | NA | 2014-07-01 | Y |
01-701-1097 | NA | ICRSP | iRECIST Confirmed Response by Investigator | N | NA | 2014-01-01 | Y |
01-701-1115 | NA | ICRSP | iRECIST Confirmed Response by Investigator | N | NA | 2012-11-30 | Y |
01-701-1118 | NA | ICRSP | iRECIST Confirmed Response by Investigator | N | NA | 2014-03-12 | Y |
01-701-1130 | WEEK 12 | ICRSP | iRECIST Confirmed Response by Investigator | Y | 2014-05-16 | 2014-02-15 | Y |
01-701-1133 | WEEK 12 | ICRSP | iRECIST Confirmed Response by Investigator | Y | 2013-01-22 | 2012-10-28 | Y |
01-701-1146 | NA | ICRSP | iRECIST Confirmed Response by Investigator | N | NA | 2013-05-20 | Y |
The following parameters may also be added:
IBCP - iRECIST Best Overall Response of CR/PR by Investigator (confirmation not required)
ICBCP - iRECIST Best Confirmed Overall Response of CR/PR by Investigator
IOVRB - iRECIST Overall Response by BICR
ILSTA - iRECIST Last Disease Assessment by Investigator
IMDIS - iRECIST Measurable Disease at Baseline by Investigator
For examples on the additional endpoints, please see Creating ADRS (Including Non-standard Endpoints).