This article describes creating an ADRS
ADaM with common oncology endpoint parameters based on RECIST v1.1. Therefore response values are expected as either CR
, PR
, SD
, NON-CR/NON-PD
, PD
or NE
.
Examples are currently presented and tested using ADSL
(ADaM) and RS
, TU
(SDTM) inputs. However, other domains could be used. 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.
AVAL
for New ParametersASEQ
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 example purpose, the SDTM and ADaM datasets (based on CDISC Pilot test data)—which are included in {admiral.test}
—are used.
library(admiral)
library(admiralonco)
library(dplyr)
library(admiral.test)
library(lubridate)
library(stringr)
data("admiral_adsl")
data("admiral_rs")
data("admiral_tu")
<- admiral_adsl
adsl <- admiral_rs
rs <- admiral_tu
tu
<- convert_blanks_to_na(rs)
rs <- convert_blanks_to_na(tu) tu
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.
<- vars(RANDDT)
adsl_vars <- derive_vars_merged(
adrs
rs,dataset_add = adsl,
new_vars = adsl_vars,
by_vars = vars(STUDYID, USUBJID)
)
USUBJID | RSTESTCD | RSDTC | VISIT | RANDDT |
---|---|---|---|---|
01-701-1015 | OVRLRESP | 2014-02-12 | WEEK 6 | 2014-01-02 |
01-701-1015 | OVRLRESP | 2014-02-12 | WEEK 6 | 2014-01-02 |
01-701-1015 | OVRLRESP | 2014-02-12 | WEEK 6 | 2014-01-02 |
01-701-1015 | OVRLRESP | 2014-03-26 | WEEK 12 | 2014-01-02 |
01-701-1015 | OVRLRESP | 2014-03-26 | WEEK 12 | 2014-01-02 |
01-701-1015 | OVRLRESP | 2014-03-26 | WEEK 12 | 2014-01-02 |
01-701-1015 | OVRLRESP | 2014-06-18 | WEEK 24 | 2014-01-02 |
01-701-1015 | OVRLRESP | 2014-06-18 | WEEK 24 | 2014-01-02 |
01-701-1015 | OVRLRESP | 2014-06-18 | WEEK 24 | 2014-01-02 |
01-703-1086 | OVRLRESP | 2012-10-13 | WEEK 6 | 2012-09-02 |
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 after date of first treatment/randomization, or rules to cover the case when a patient has multiple observations per visit (e.g. by selecting 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 = "Recist 1.1"
)
USUBJID | VISIT | RSTESTCD | RSEVAL | PARAMCD | PARAM | PARCAT1 | PARCAT2 | PARCAT3 |
---|---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | Recist 1.1 |
01-701-1015 | WEEK 12 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | Recist 1.1 |
01-701-1015 | WEEK 24 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | Recist 1.1 |
01-703-1086 | WEEK 6 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | Recist 1.1 |
01-703-1086 | WEEK 12 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | Recist 1.1 |
01-716-1024 | WEEK 6 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | Recist 1.1 |
01-716-1024 | WEEK 12 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | Recist 1.1 |
01-716-1024 | WEEK 18 (T) | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | Recist 1.1 |
01-716-1024 | WEEK 24 | OVRLRESP | INVESTIGATOR | OVR | Overall Response by Investigator | Tumor Response | Investigator | Recist 1.1 |
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 | PR | 2014-02-12 | 2014-02-12 | NA |
01-701-1015 | WEEK 12 | OVR | Overall Response by Investigator | CR | 2014-03-26 | 2014-03-26 | NA |
01-701-1015 | WEEK 24 | OVR | Overall Response by Investigator | PD | 2014-06-18 | 2014-06-18 | NA |
01-703-1086 | WEEK 6 | OVR | Overall Response by Investigator | SD | 2012-10-13 | 2012-10-13 | NA |
01-703-1086 | WEEK 12 | OVR | Overall Response by Investigator | SD | 2012-11-27 | 2012-11-27 | NA |
01-716-1024 | WEEK 6 | OVR | Overall Response by Investigator | SD | 2012-08-24 | 2012-08-24 | NA |
01-716-1024 | WEEK 12 | OVR | Overall Response by Investigator | SD | 2012-09-30 | 2012-09-30 | NA |
01-716-1024 | WEEK 18 (T) | OVR | Overall Response by Investigator | PR | 2012-11-17 | 2012-11-17 | NA |
01-716-1024 | WEEK 24 | OVR | Overall Response by Investigator | SD | 2012-12-30 | 2012-12-30 | NA |
AVALC
and AVAL
Here we populate AVALC
and create the numeric version as AVAL
(ordered from best to worst response). This ordering is already covered within our RECIST v1.1 parameter derivation functions, and so changing AVAL
here would not change the result of those derivations.
<- adrs %>%
adrs mutate(
AVALC = RSSTRESC,
AVAL = aval_resp(AVALC)
)
USUBJID | AVISIT | PARAMCD | PARAM | RSSTRESC | AVALC | AVAL |
---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | OVR | Overall Response by Investigator | PR | PR | 2 |
01-701-1015 | WEEK 12 | OVR | Overall Response by Investigator | CR | CR | 1 |
01-701-1015 | WEEK 24 | OVR | Overall Response by Investigator | PD | PD | 5 |
01-703-1086 | WEEK 6 | OVR | Overall Response by Investigator | SD | SD | 3 |
01-703-1086 | WEEK 12 | OVR | Overall Response by Investigator | SD | SD | 3 |
01-716-1024 | WEEK 6 | OVR | Overall Response by Investigator | SD | SD | 3 |
01-716-1024 | WEEK 12 | OVR | Overall Response by Investigator | SD | SD | 3 |
01-716-1024 | WEEK 18 (T) | OVR | Overall Response by Investigator | PR | PR | 2 |
01-716-1024 | WEEK 24 | OVR | Overall Response by Investigator | SD | SD | 3 |
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 = vars(STUDYID, USUBJID, ADT),
order = vars(AVAL, RSSEQ),
new_var = ANL01FL,
mode = "last"
),filter = !is.na(AVAL) & ADT >= RANDDT
)
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | RANDDT | ANL01FL |
---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | OVR | Overall Response by Investigator | PR | 2014-02-12 | 2014-01-02 | Y |
01-701-1015 | WEEK 12 | OVR | Overall Response by Investigator | CR | 2014-03-26 | 2014-01-02 | Y |
01-701-1015 | WEEK 24 | OVR | Overall Response by Investigator | PD | 2014-06-18 | 2014-01-02 | Y |
01-703-1086 | WEEK 6 | OVR | Overall Response by Investigator | SD | 2012-10-13 | 2012-09-02 | Y |
01-703-1086 | WEEK 12 | OVR | Overall Response by Investigator | SD | 2012-11-27 | 2012-09-02 | Y |
01-716-1024 | WEEK 6 | OVR | Overall Response by Investigator | SD | 2012-08-24 | 2012-07-09 | Y |
01-716-1024 | WEEK 12 | OVR | Overall Response by Investigator | SD | 2012-09-30 | 2012-07-09 | Y |
01-716-1024 | WEEK 18 (T) | OVR | Overall Response by Investigator | PR | 2012-11-17 | 2012-07-09 | Y |
01-716-1024 | WEEK 24 | OVR | Overall Response by Investigator | SD | 2012-12-30 | 2012-07-09 | 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).
<- adrs %>%
adrs mutate(
ANL01FL = case_when(
!is.na(AVAL) & ADT >= RANDDT & ADT < NACTDT ~ "Y",
TRUE ~ NA_character_
) )
Note here that we don’t filter out records after first PD
at this stage, as that is specifically catered for in the {admiralonco}
parameter derivation functions in the below steps, via source_pd
arguments.
ANL02FL
However, if you prefer not to rely on source_pd
arguments, then the user is free to filter out records after first PD
at this stage in a similar way via a ANLzzFL
flag, and then you could leave source_pd
as null in all downstream parameter derivation function calls. So, for example the user could create ANL02FL
flag to subset the post-baseline response data up to and including first reported progressive disease. This would be an alternative and transparent method to the use of source_pd
argument approach to create ADRS parameters below. Using {admiral}
function admiral::derive_var_relative_flag()
we could create ANL02FL
as below.
<- adrs %>%
adrs derive_var_relative_flag(
by_vars = vars(USUBJID),
order = vars(ADT, AVISITN),
new_var = ANL02FL,
condition = AVALC == "PD",
mode = "first",
selection = "before",
inclusive = TRUE
)
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.
The function admiral::derive_param_extreme_event()
can be used to find the date of first PD
.
<- adrs %>%
adrs derive_param_extreme_event(
dataset_adsl = adsl,
dataset_source = adrs,
filter_source = PARAMCD == "OVR" & AVALC == "PD" & ANL01FL == "Y",
order = vars(ADT, RSSEQ),
set_values_to = vars(
PARAMCD = "PD",
PARAM = "Disease Progression by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | ANL01FL |
---|---|---|---|---|---|---|
01-701-1015 | WEEK 24 | PD | Disease Progression by Investigator | Y | 2014-06-18 | Y |
01-701-1023 | NA | PD | Disease Progression by Investigator | N | NA | Y |
01-703-1086 | NA | PD | Disease Progression by Investigator | N | NA | Y |
01-703-1096 | NA | PD | Disease Progression by Investigator | N | NA | Y |
01-707-1037 | NA | PD | Disease Progression by Investigator | N | NA | Y |
01-716-1024 | NA | PD | Disease Progression by Investigator | N | NA | Y |
For progressive disease, response and death parameters 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 PD
as a variable, rather than as a new parameter record. All the parameter derivation functions that use these dates are flexible to allow sourcing these from any input source using admiral::date_source()
. See examples below.
The next required step is to define the source location for this newly derived PD
date.
<- date_source(
pd dataset_name = "adrs",
date = ADT,
filter = PARAMCD == "PD" & AVALC == "Y"
)
An equivalent example if using ADSL
instead could be as follows (where PDDT
would be pre-derived as first date of progressive disease).
<- date_source(
pd dataset_name = "adsl",
date = PDDT
)
The function derive_param_response()
can then be used to find the date of first response. This differs from the admiral::derive_param_extreme_event()
function in that it only looks for events occurring prior to first PD
. In the below example, the response condition has been defined as CR
or PR
.
<- adrs %>%
adrs derive_param_response(
dataset_adsl = adsl,
filter_source = PARAMCD == "OVR" & AVALC %in% c("CR", "PR") & ANL01FL == "Y",
source_pd = pd,
source_datasets = list(adrs = adrs),
set_values_to = vars(
PARAMCD = "RSP",
PARAM = "Response by Investigator (confirmation not required)",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | ANL01FL |
---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | RSP | Response by Investigator (confirmation not required) | Y | 2014-02-12 | Y |
01-716-1024 | WEEK 18 (T) | RSP | Response by Investigator (confirmation not required) | Y | 2012-11-17 | Y |
01-701-1023 | NA | RSP | Response by Investigator (confirmation not required) | N | NA | Y |
01-703-1086 | NA | RSP | Response by Investigator (confirmation not required) | N | NA | Y |
01-703-1096 | NA | RSP | Response by Investigator (confirmation not required) | N | NA | Y |
01-707-1037 | NA | RSP | Response by Investigator (confirmation not required) | N | NA | Y |
Similarly, we now define the source location for this newly derived first response date.
<- date_source(
resp dataset_name = "adrs",
date = ADT,
filter = PARAMCD == "RSP" & AVALC == "Y"
)
The function derive_param_clinbenefit()
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 PD
. This could also be known as disease control. In this example the “sustained period” has been defined as 42 days after randomization date, using the ref_start_window
argument.
<- adrs %>%
adrs derive_param_clinbenefit(
dataset_adsl = adsl,
filter_source = PARAMCD == "OVR" & ANL01FL == "Y",
source_resp = resp,
source_pd = pd,
source_datasets = list(adrs = adrs),
reference_date = RANDDT,
ref_start_window = 42,
set_values_to = vars(
PARAMCD = "CB",
PARAM = "Clinical Benefit by Investigator (confirmation for response not required)",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | RANDDT | ANL01FL |
---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | CB | Clinical Benefit by Investigator (confirmation for response not required) | Y | 2014-02-12 | 2014-01-02 | Y |
01-701-1023 | NA | CB | Clinical Benefit by Investigator (confirmation for response not required) | N | NA | 2012-08-05 | Y |
01-703-1086 | WEEK 12 | CB | Clinical Benefit by Investigator (confirmation for response not required) | Y | 2012-11-27 | 2012-09-02 | Y |
01-703-1096 | NA | CB | Clinical Benefit by Investigator (confirmation for response not required) | N | NA | 2013-01-25 | Y |
01-707-1037 | NA | CB | Clinical Benefit by Investigator (confirmation for response not required) | N | NA | 2013-12-20 | Y |
01-716-1024 | WEEK 6 | CB | Clinical Benefit by Investigator (confirmation for response not required) | Y | 2012-08-24 | 2012-07-09 | Y |
The function derive_param_bor()
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 a SD
or NON-CR/NON-PD
as being eligible from. In this example, 42 days after randomization date has been used again.
<- adrs %>%
adrs derive_param_bor(
dataset_adsl = adsl,
filter_source = PARAMCD == "OVR" & ANL01FL == "Y",
source_pd = pd,
source_datasets = list(adrs = adrs),
reference_date = RANDDT,
ref_start_window = 42,
set_values_to = vars(
PARAMCD = "BOR",
PARAM = "Best Overall Response by Investigator (confirmation not required)",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | RANDDT | ANL01FL |
---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 12 | BOR | Best Overall Response by Investigator (confirmation not required) | CR | 2014-03-26 | 2014-01-02 | Y |
01-701-1023 | NA | BOR | Best Overall Response by Investigator (confirmation not required) | MISSING | NA | 2012-08-05 | Y |
01-703-1086 | WEEK 12 | BOR | Best Overall Response by Investigator (confirmation not required) | SD | 2012-11-27 | 2012-09-02 | Y |
01-703-1096 | NA | BOR | Best Overall Response by Investigator (confirmation not required) | MISSING | NA | 2013-01-25 | Y |
01-707-1037 | NA | BOR | Best Overall Response by Investigator (confirmation not required) | MISSING | NA | 2013-12-20 | Y |
01-716-1024 | WEEK 18 (T) | BOR | Best Overall Response by Investigator (confirmation not required) | PR | 2012-11-17 | 2012-07-09 | Y |
Note that the above gives pre-defined AVAL
values of: "CR" ~ 1
, "PR" ~ 2
, "SD" ~ 3
, "NON-CR/NON-PD" ~ 4
, "PD" ~ 5
, "NE" ~ 6
, "MISSING" ~ 7
.
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(
== "CR" ~ 7,
arg == "PR" ~ 6,
arg == "SD" ~ 5,
arg == "NON-CR/NON-PD" ~ 4,
arg == "PD" ~ 3,
arg == "NE" ~ 2,
arg == "MISSING" ~ 1,
arg TRUE ~ NA_real_
) }
Then add the additional argument aval_fun = aval_resp_new
to the above derive_param_bor()
call. Be aware that this will only impact the AVAL
mapping, not the derivation of BOR in any way - as the function derivation relies only on AVALC
here.
The function admiral::derive_param_extreme_event()
can be used to check if a patient had a response for BOR.
<- adrs %>%
adrs derive_param_extreme_event(
dataset_adsl = adsl,
dataset_source = adrs,
filter_source = PARAMCD == "BOR" & AVALC %in% c("CR", "PR") & ANL01FL == "Y",
order = vars(ADT, RSSEQ),
set_values_to = vars(
PARAMCD = "BCP",
PARAM = "Best Overall Response of CR/PR by Investigator (confirmation not required)",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | ANL01FL |
---|---|---|---|---|---|---|
01-701-1015 | WEEK 12 | BCP | Best Overall Response of CR/PR by Investigator (confirmation not required) | Y | 2014-03-26 | Y |
01-716-1024 | WEEK 18 (T) | BCP | Best Overall Response of CR/PR by Investigator (confirmation not required) | Y | 2012-11-17 | Y |
01-701-1023 | NA | BCP | Best Overall Response of CR/PR by Investigator (confirmation not required) | N | NA | Y |
01-703-1086 | NA | BCP | Best Overall Response of CR/PR by Investigator (confirmation not required) | N | NA | Y |
01-703-1096 | NA | BCP | Best Overall Response of CR/PR by Investigator (confirmation not required) | N | NA | Y |
01-707-1037 | NA | BCP | Best Overall Response of CR/PR by Investigator (confirmation not required) | N | NA | Y |
Any of the above response parameters can be repeated for “confirmed” responses only. For these the functions derive_param_confirmed_resp()
and derive_param_confirmed_bor()
can be used. 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 ref_confirm
argument.
<- adrs %>%
adrs derive_param_confirmed_resp(
dataset_adsl = adsl,
filter_source = PARAMCD == "OVR" & AVALC %in% c("CR", "PR") & ANL01FL == "Y",
source_pd = pd,
source_datasets = list(adrs = adrs),
ref_confirm = 28,
set_values_to = vars(
PARAMCD = "CRSP",
PARAM = "Confirmed Response by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
)
)
<- date_source(
confirmed_resp dataset_name = "adrs",
date = ADT,
filter = PARAMCD == "CRSP" & AVALC == "Y"
)
<- adrs %>%
adrs derive_param_clinbenefit(
dataset_adsl = adsl,
filter_source = PARAMCD == "OVR" & ANL01FL == "Y",
source_resp = confirmed_resp,
source_pd = pd,
source_datasets = list(adrs = adrs),
reference_date = RANDDT,
ref_start_window = 42,
set_values_to = vars(
PARAMCD = "CCB",
PARAM = "Confirmed Clinical Benefit by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
)%>%
) derive_param_confirmed_bor(
dataset_adsl = adsl,
filter_source = PARAMCD == "OVR" & ANL01FL == "Y",
source_pd = pd,
source_datasets = list(adrs = adrs),
reference_date = RANDDT,
ref_start_window = 42,
ref_confirm = 28,
set_values_to = vars(
PARAMCD = "CBOR",
PARAM = "Best Confirmed Overall Response by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
)%>%
) derive_param_extreme_event(
dataset_adsl = adsl,
dataset_source = adrs,
filter_source = PARAMCD == "CBOR" & AVALC %in% c("CR", "PR") & ANL01FL == "Y",
order = vars(ADT, RSSEQ),
set_values_to = vars(
PARAMCD = "CBCP",
PARAM = "Best Confirmed Overall Response of CR/PR by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | RANDDT | ANL01FL |
---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | CRSP | Confirmed Response by Investigator | Y | 2014-02-12 | 2014-01-02 | Y |
01-701-1023 | NA | CRSP | Confirmed Response by Investigator | N | NA | 2012-08-05 | Y |
01-703-1086 | NA | CRSP | Confirmed Response by Investigator | N | NA | 2012-09-02 | Y |
01-703-1096 | NA | CRSP | Confirmed Response by Investigator | N | NA | 2013-01-25 | Y |
01-707-1037 | NA | CRSP | Confirmed Response by Investigator | N | NA | 2013-12-20 | Y |
01-716-1024 | NA | CRSP | Confirmed Response by Investigator | N | NA | 2012-07-09 | Y |
01-701-1015 | WEEK 6 | CCB | Confirmed Clinical Benefit by Investigator | Y | 2014-02-12 | 2014-01-02 | Y |
01-701-1023 | NA | CCB | Confirmed Clinical Benefit by Investigator | N | NA | 2012-08-05 | Y |
01-703-1086 | WEEK 12 | CCB | Confirmed Clinical Benefit by Investigator | Y | 2012-11-27 | 2012-09-02 | Y |
01-703-1096 | NA | CCB | Confirmed Clinical Benefit by Investigator | N | NA | 2013-01-25 | Y |
All of the above steps can be repeated for different sets of records, such as now using assessments from the IRF/BICR instead of investigator. For this you would just need to replace the first steps with selecting the required records, and then feed these as input to the downstream parameter functions.
Remember that a new progressive disease and response source object would be required for passing to source_pd
and source_resp
respectively.
<- rs %>%
adrsirf filter(RSEVAL == "INDEPENDENT ASSESSOR" & RSEVALID == "RADIOLOGIST 1" & RSTESTCD == "OVRLRESP") %>%
mutate(
PARAMCD = "OVRR1",
PARAM = "Overall Response by Radiologist 1",
PARCAT1 = "Tumor Response",
PARCAT2 = "Radiologist",
PARCAT3 = "Recist 1.1"
)
USUBJID | VISIT | RSTESTCD | RSEVAL | PARAMCD | PARAM | PARCAT1 | PARCAT2 | PARCAT3 |
---|---|---|---|---|---|---|---|---|
01-701-1015 | WEEK 6 | OVRLRESP | INDEPENDENT ASSESSOR | OVRR1 | Overall Response by Radiologist 1 | Tumor Response | Radiologist | Recist 1.1 |
01-701-1015 | WEEK 12 | OVRLRESP | INDEPENDENT ASSESSOR | OVRR1 | Overall Response by Radiologist 1 | Tumor Response | Radiologist | Recist 1.1 |
01-701-1015 | WEEK 24 | OVRLRESP | INDEPENDENT ASSESSOR | OVRR1 | Overall Response by Radiologist 1 | Tumor Response | Radiologist | Recist 1.1 |
01-703-1086 | WEEK 6 | OVRLRESP | INDEPENDENT ASSESSOR | OVRR1 | Overall Response by Radiologist 1 | Tumor Response | Radiologist | Recist 1.1 |
01-703-1086 | WEEK 12 | OVRLRESP | INDEPENDENT ASSESSOR | OVRR1 | Overall Response by Radiologist 1 | Tumor Response | Radiologist | Recist 1.1 |
01-716-1024 | WEEK 6 | OVRLRESP | INDEPENDENT ASSESSOR | OVRR1 | Overall Response by Radiologist 1 | Tumor Response | Radiologist | Recist 1.1 |
01-716-1024 | WEEK 12 | OVRLRESP | INDEPENDENT ASSESSOR | OVRR1 | Overall Response by Radiologist 1 | Tumor Response | Radiologist | Recist 1.1 |
01-716-1024 | WEEK 18 (T) | OVRLRESP | INDEPENDENT ASSESSOR | OVRR1 | Overall Response by Radiologist 1 | Tumor Response | Radiologist | Recist 1.1 |
01-716-1024 | WEEK 24 | OVRLRESP | INDEPENDENT ASSESSOR | OVRR1 | Overall Response by Radiologist 1 | Tumor Response | Radiologist | Recist 1.1 |
Then in all the calls to the parameter derivation functions you would replace the PARAMCD == "OVR"
source with PARAMCD == "OVRR1"
.
The function admiral::derive_param_extreme_event()
can be used to create a new death parameter using death date from ADSL
. We need to restrict the columns from ADSL
as we’ll merge all required variables later across all our ADRS
records.
<- adsl %>%
adsldth select(STUDYID, USUBJID, DTHDT, !!!adsl_vars)
<- adrs %>%
adrs derive_param_extreme_event(
dataset_adsl = adsldth,
dataset_source = adsldth,
filter_source = !is.na(DTHDT),
set_values_to = vars(
PARAMCD = "DEATH",
PARAM = "Death",
PARCAT1 = "Reference Event",
ANL01FL = "Y",
ADT = DTHDT
)%>%
) select(-DTHDT)
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | ANL01FL |
---|---|---|---|---|---|---|
01-701-1015 | NA | DEATH | Death | N | NA | Y |
01-701-1023 | NA | DEATH | Death | N | NA | Y |
01-703-1086 | NA | DEATH | Death | N | NA | Y |
01-703-1096 | NA | DEATH | Death | N | NA | Y |
01-707-1037 | NA | DEATH | Death | N | NA | Y |
01-716-1024 | NA | DEATH | Death | N | NA | Y |
The function admiral::derive_param_extreme_event()
can be used to create a parameter for last disease assessment. We need to set new_var
to a dummy variable here, or otherwise the original AVALC
value from the record would be overwritten with "Y"
.
<- adrs %>%
adrs derive_param_extreme_event(
dataset_adsl = adsl,
dataset_source = adrs,
filter_source = PARAMCD == "OVR" & ANL01FL == "Y",
order = vars(ADT, RSSEQ),
mode = "last",
new_var = dummy,
set_values_to = vars(
PARAMCD = "LSTA",
PARAM = "Last Disease Assessment by Investigator",
PARCAT1 = "Tumor Response",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
)%>%
) select(-dummy)
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | ANL01FL |
---|---|---|---|---|---|---|
01-701-1015 | WEEK 24 | LSTA | Last Disease Assessment by Investigator | PD | 2014-06-18 | Y |
01-703-1086 | WEEK 12 | LSTA | Last Disease Assessment by Investigator | SD | 2012-11-27 | Y |
01-716-1024 | WEEK 24 | LSTA | Last Disease Assessment by Investigator | SD | 2012-12-30 | Y |
01-701-1023 | NA | LSTA | Last Disease Assessment by Investigator | NA | NA | Y |
01-703-1096 | NA | LSTA | Last Disease Assessment by Investigator | NA | NA | Y |
01-707-1037 | NA | LSTA | Last Disease Assessment by Investigator | NA | NA | Y |
The function admiral::derive_param_exist_flag()
can be used to check whether a patient has measurable disease at baseline, according to a company-specific condition. In this example we check TU
for target lesions during the baseline visit. We need to restrict the columns from ADSL
as we’ll merge all required variables later across all our ADRS
records.
<- adsl %>%
adslmdis select(STUDYID, USUBJID, !!!adsl_vars)
<- adrs %>%
adrs derive_param_exist_flag(
dataset_adsl = adslmdis,
dataset_add = tu,
condition = TUEVAL == "INVESTIGATOR" & TUSTRESC == "TARGET" & VISIT == "BASELINE",
false_value = "N",
missing_value = "N",
set_values_to = vars(
PARAMCD = "MDIS",
PARAM = "Measurable Disease at Baseline by Investigator",
PARCAT2 = "Investigator",
PARCAT3 = "Recist 1.1",
ANL01FL = "Y"
) )
USUBJID | AVISIT | PARAMCD | PARAM | AVALC | ADT | ANL01FL |
---|---|---|---|---|---|---|
01-701-1015 | NA | MDIS | Measurable Disease at Baseline by Investigator | Y | NA | Y |
01-701-1023 | NA | MDIS | Measurable Disease at Baseline by Investigator | Y | NA | Y |
01-703-1086 | NA | MDIS | Measurable Disease at Baseline by Investigator | Y | NA | Y |
01-703-1096 | NA | MDIS | Measurable Disease at Baseline by Investigator | Y | NA | Y |
01-707-1037 | NA | MDIS | Measurable Disease at Baseline by Investigator | Y | NA | Y |
01-716-1024 | NA | MDIS | Measurable Disease at Baseline by Investigator | Y | NA | Y |
AVAL
for New ParametersFor cases where AVALC
has been derived for new parameters above as "Y"
or "N"
, we need to set AVAL
to numeric versions such as 1
/0
.
<- adrs %>%
adrs mutate(
AVAL = case_when(
== "Y" ~ 1,
AVALC == "N" ~ 0,
AVALC TRUE ~ AVAL
) )
USUBJID | PARAMCD | AVALC | AVAL |
---|---|---|---|
01-701-1015 | RSP | Y | 1 |
01-701-1015 | PD | Y | 1 |
01-701-1015 | CB | Y | 1 |
01-701-1015 | BCP | Y | 1 |
01-701-1015 | CRSP | Y | 1 |
01-701-1015 | CCB | Y | 1 |
01-701-1015 | CBCP | N | 0 |
01-701-1015 | DEATH | N | 0 |
01-701-1015 | MDIS | Y | 1 |
ASEQ
The function admiral::derive_var_obs_number()
can be used to derive ASEQ
. An example call is:
<- adrs %>%
adrs derive_var_obs_number(
by_vars = vars(STUDYID, USUBJID),
order = vars(PARAMCD, ADT, VISITNUM, RSSEQ),
check_type = "error"
)
USUBJID | PARAMCD | ADT | VISITNUM | AVISIT | ASEQ |
---|---|---|---|---|---|
01-701-1015 | BCP | 2014-03-26 | 9 | WEEK 12 | 1 |
01-701-1015 | BOR | 2014-03-26 | 9 | WEEK 12 | 2 |
01-701-1015 | CB | 2014-02-12 | 7 | WEEK 6 | 3 |
01-701-1015 | CBCP | NA | NA | NA | 4 |
01-701-1015 | CBOR | 2014-02-12 | 7 | WEEK 6 | 5 |
01-701-1015 | CCB | 2014-02-12 | 7 | WEEK 6 | 6 |
01-701-1015 | CRSP | 2014-02-12 | 7 | WEEK 6 | 7 |
01-701-1015 | DEATH | NA | NA | NA | 8 |
01-701-1015 | LSTA | 2014-06-18 | 12 | WEEK 24 | 9 |
01-701-1015 | MDIS | NA | NA | NA | 10 |
If needed, the other ADSL
variables can now be added. List of ADSL variables already merged held in vector adsl_vars
.
<- adrs %>%
adrs derive_vars_merged(
dataset_add = select(adsl, !!!negate_vars(adsl_vars)),
by_vars = vars(STUDYID, USUBJID)
)
USUBJID | RFSTDTC | RFENDTC | DTHDTC | DTHFL | AGE | AGEU |
---|---|---|---|---|---|---|
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
01-701-1015 | 2014-01-02 | 2014-07-02 | NA | NA | 63 | YEARS |
ADaM | Sample Code |
---|---|
ADRS | ad_adrs.R |