The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
This article describes creating a vital signs ADaM for metabolic clinical trials.
We advise you first consult the {admiral}
Creating
a BDS Finding ADaM vignette. The programming workflow around
creating the general set-up of an ADVS
using
{admiral}
functions is the same. In this vignette, we focus
on the most common endpoints and their derivations mainly found in
metabolic trials to avoid repeating information and maintaining the same
content in two places. As such, the code in this vignette is not
completely executable; we recommend consulting the ADVS template script
to view the full workflow.
PARAMCD
, PARAM
,
PARAMN
, PARCAT1
To start, all data frames needed for the creation of
ADVS
should be loaded into the global environment. Reading
data will usually be a company specific process, however, for the
purpose of this vignette, we will use example data from
{pharmaversesdtm}
and {admiral}
. We will
utilize DM
, VS
and ADSL
for the
basis of ADVS
.
dm_metabolic <- admiralmetabolic::dm_metabolic
vs_metabolic <- admiralmetabolic::vs_metabolic
admiral_adsl <- admiral::admiral_adsl
dm <- convert_blanks_to_na(dm_metabolic)
vs <- convert_blanks_to_na(vs_metabolic)
admiral_adsl <- convert_blanks_to_na(admiral_adsl)
Within this vignette, DM
is used as the basis for
ADSL
:
# Retrieve required variables from admiral ADSL for this vignette that are not present in DM dataset
adsl <- dm %>%
select(-DOMAIN) %>%
mutate(TRT01P = ARM, TRT01A = ACTARM) %>%
left_join(admiral_adsl %>% select(USUBJID, TRTSDT, TRTEDT), by = "USUBJID")
The following steps are to merge ADSL
variables with the
source data and derive the usual ADVS
analysis variables.
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 {admiral}
Creating
a BDS Finding ADaM vignette.
PARAMCD
, PARAM
,
PARAMN
, PARCAT1
variablesThe next step is to create and assign parameter level variables such
as PARAMCD
, PARAM
, PARAMN
,
PARCAT1
, etc. For this, a lookup can be created based on
the SDTM --TESTCD
value to join to the source data. One key
addition in metabolic trials are vital sign parameters associated to
body measurements, such as BMI
, HIPCIR
, and
WSTCIR
.
param_lookup <- tribble(
~VSTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, ~PARCAT1, ~PARCAT1N,
"HEIGHT", "HEIGHT", "Height (cm)", 1, "Anthropometric Measurement", 1,
"WEIGHT", "WEIGHT", "Weight (kg)", 2, "Anthropometric Measurement", 1,
"BMI", "BMI", "Body Mass Index(kg/m^2)", 3, "Anthropometric Measurement", 1,
"HIPCIR", "HIPCIR", "Hip Circumference (cm)", 4, "Anthropometric Measurement", 1,
"WSTCIR", "WSTCIR", "Waist Circumference (cm)", 5, "Anthropometric Measurement", 1,
"DIABP", "DIABP", "Diastolic Blood Pressure (mmHg)", 6, "Vital Sign", 2,
"PULSE", "PULSE", "Pulse Rate (beats/min)", 7, "Vital Sign", 2,
"SYSBP", "SYSBP", "Systolic Blood Pressure (mmHg)", 8, "Vital Sign", 2,
"TEMP", "TEMP", "Temperature (C)", 9, "Vital Sign", 2
)
This lookup may now be joined to the source data and this is how the parameters will look like:
advs <- derive_vars_merged_lookup(
advs,
dataset_add = param_lookup,
new_vars = exprs(PARAMCD, PARAM, PARAMN, PARCAT1, PARCAT1N),
by_vars = exprs(VSTESTCD)
)
USUBJID | VSTESTCD | PARAMCD | PARAM | PARCAT1 | PARCAT1N |
---|---|---|---|---|---|
01-701-1015 | BMI | BMI | Body Mass Index(kg/m^2) | Anthropometric Measurement | 1 |
01-701-1015 | DIABP | DIABP | Diastolic Blood Pressure (mmHg) | Vital Sign | 2 |
01-701-1015 | HEIGHT | HEIGHT | Height (cm) | Anthropometric Measurement | 1 |
01-701-1015 | HIPCIR | HIPCIR | Hip Circumference (cm) | Anthropometric Measurement | 1 |
01-701-1015 | PULSE | PULSE | Pulse Rate (beats/min) | Vital Sign | 2 |
01-701-1015 | SYSBP | SYSBP | Systolic Blood Pressure (mmHg) | Vital Sign | 2 |
01-701-1015 | TEMP | TEMP | Temperature (C) | Vital Sign | 2 |
01-701-1015 | WEIGHT | WEIGHT | Weight (kg) | Anthropometric Measurement | 1 |
01-701-1015 | WSTCIR | WSTCIR | Waist Circumference (cm) | Anthropometric Measurement | 1 |
01-701-1023 | BMI | BMI | Body Mass Index(kg/m^2) | Anthropometric Measurement | 1 |
In clinical trials focused on metabolic conditions, it’s common to derive additional parameters from the collected data. These derived parameters often provide valuable insights into the metabolic health of the subjects. In this vignette, we will explore how one could derive BMI and waist-hip ratio.
In metabolic trials, BMI
is often calculated at source.
But while creating the ADVS
dataset, we re-derive
BMI
from the collected height and weight values. This is
done to ensure that the BMI
is calculated consistently
across all subjects and visits.
In this step, we create parameter Body Mass Index (BMI
)
for the ADVS
domain using the
derive_param_bmi()
function. Note that only variables
specified in the by_vars
argument will be populated in the
newly created records. Also note that if height is collected only once
for a subject use constant_by_vars
to specify the function
to merge by the subject-level variable - otherwise BMI is only
calculated for visits where both are collected.
# Remove BMI collected in SDTM
advs <- advs %>% filter(VSTESTCD != "BMI" | is.na(VSTESTCD))
# Re-calculate BMI
advs <- derive_param_bmi(
advs,
by_vars = c(
get_admiral_option("subject_keys"),
exprs(!!!adsl_vars, VISIT, VISITNUM, ADT, ADY, VSTPT, VSTPTNUM)
),
set_values_to = exprs(
PARAMCD = "BMI",
PARAM = "Body Mass Index (kg/m^2)",
PARAMN = 3,
PARCAT1 = "Anthropometric Measurement",
PARCAT1N = 1
),
get_unit_expr = VSSTRESU,
constant_by_vars = exprs(USUBJID)
)
USUBJID | VSTESTCD | PARAMCD | PARAM | VISIT | AVAL |
---|---|---|---|---|---|
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | SCREENING 1 | 38.10500 |
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | BASELINE | 38.06228 |
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | WEEK 2 | 38.53219 |
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | WEEK 4 | 38.62617 |
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | WEEK 6 | 38.67743 |
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | WEEK 8 | 38.79277 |
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | WEEK 12 | 38.95937 |
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | WEEK 16 | 38.57918 |
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | WEEK 20 | 39.03200 |
01-701-1015 | NA | BMI | Body Mass Index (kg/m^2) | WEEK 24 | 39.10889 |
Metabolic trials often include ratios between different
anthropometric measurements. For this, {admiralmetabolic}
provides several functions to quickly calculate various anthropometric
ratios. For instance, the function derive_param_waisthip()
can be used to derive the waist-hip ratio.
advs <- advs %>%
derive_param_waisthip(
by_vars = exprs(!!!get_admiral_option("subject_keys"), VISIT, VISITNUM),
wstcir_code = "WSTCIR",
hipcir_code = "HIPCIR",
set_values_to = exprs(
PARAMCD = "WAISTHIP",
PARAM = "Waist to Hip Ratio"
),
get_unit_expr = VSSTRESU
)
USUBJID | PARAMCD | PARAM | VISIT | AVAL |
---|---|---|---|---|
01-701-1033 | WAISTHIP | Waist to Hip Ratio | BASELINE | 0.9727273 |
01-701-1034 | WAISTHIP | Waist to Hip Ratio | BASELINE | 0.9607352 |
01-701-1034 | WAISTHIP | Waist to Hip Ratio | WEEK 16 | 0.9495652 |
01-701-1034 | WAISTHIP | Waist to Hip Ratio | WEEK 20 | 0.9561404 |
01-701-1034 | WAISTHIP | Waist to Hip Ratio | WEEK 24 | 0.9557522 |
01-701-1034 | WAISTHIP | Waist to Hip Ratio | WEEK 26 | 0.9469027 |
In the following sections, we will explore some of the most common endpoints typically observed in metabolic trials.
One such endpoint is the improvement in weight category from baseline
to the end of treatment, which is often assessed using Body Mass Index
(BMI
). To capture this, we will derive variables such as
AVALCATy
and BASECATy
, as detailed in the
subsequent section.
Additionally, the achievement of weight reduction thresholds, such as
>= 5%, >= 10%, or >= 15% from baseline to end of treatment or
at a certain visit, is a common endpoint in metabolic trials. To
accommodate these criteria, we will derive relevant criterion variables
such as CRITy
, CRITyFL
, and
CRITyFLN
, with the necessary functions provided by
{admiral}
outlined below.
AVALCATy
,
BASECATy
)For deriving categorization variables (AVALCATy
,
BASECATy
) {admiral}
provides derive_vars_cat()
(see documentation of the function for details).
avalcat_lookup <- exprs(
~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N,
"BMI", AVAL < 18.5, "Underweight", 1,
"BMI", AVAL >= 18.5 & AVAL < 25, "Normal weight", 2,
"BMI", AVAL >= 25 & AVAL < 30, "Overweight", 3,
"BMI", AVAL >= 30 & AVAL < 35, "Obesity class I", 4,
"BMI", AVAL >= 35 & AVAL < 40, "Obesity class II", 5,
"BMI", AVAL >= 40, "Obesity class III", 6,
"BMI", is.na(AVAL), NA_character_, NA_integer_
)
# Derive BMI class (AVALCAT1, AVALCA1N)
advs <- advs %>%
derive_vars_cat(
definition = avalcat_lookup,
by_vars = exprs(PARAMCD)
)
USUBJID | PARAMCD | VISIT | AVAL | AVALCA1N | AVALCAT1 |
---|---|---|---|---|---|
01-701-1023 | BMI | SCREENING 1 | 38.55257 | 5 | Obesity class II |
01-701-1023 | BMI | BASELINE | 38.52106 | 5 | Obesity class II |
01-701-1023 | BMI | WEEK 2 | 38.97272 | 5 | Obesity class II |
01-701-1023 | BMI | WEEK 4 | 39.28784 | 5 | Obesity class II |
01-701-1034 | BMI | SCREENING 1 | 40.69404 | 6 | Obesity class III |
01-701-1034 | BMI | BASELINE | 40.43434 | 6 | Obesity class III |
01-701-1034 | BMI | WEEK 2 | 39.67406 | 5 | Obesity class II |
01-701-1034 | BMI | WEEK 4 | 39.48963 | 5 | Obesity class II |
01-701-1034 | BMI | WEEK 6 | 39.01163 | 5 | Obesity class II |
01-701-1034 | BMI | WEEK 8 | 38.81215 | 5 | Obesity class II |
Now we can use derive_var_base
to derive the
BASECATy
/ BASECAyN
variables.
advs <- advs %>%
derive_var_base(
by_vars = exprs(!!!get_admiral_option("subject_keys"), PARAMCD),
source_var = AVALCAT1,
new_var = BASECAT1
) %>%
derive_var_base(
by_vars = exprs(!!!get_admiral_option("subject_keys"), PARAMCD),
source_var = AVALCA1N,
new_var = BASECA1N
)
USUBJID | PARAMCD | VISIT | AVAL | BASE | ABLFL | BASECA1N | BASECAT1 |
---|---|---|---|---|---|---|---|
01-701-1023 | BMI | SCREENING 1 | 38.55257 | 38.52106 | NA | 5 | Obesity class II |
01-701-1023 | BMI | BASELINE | 38.52106 | 38.52106 | Y | 5 | Obesity class II |
01-701-1023 | BMI | WEEK 2 | 38.97272 | 38.52106 | NA | 5 | Obesity class II |
01-701-1023 | BMI | WEEK 4 | 39.28784 | 38.52106 | NA | 5 | Obesity class II |
01-701-1034 | BMI | SCREENING 1 | 40.69404 | 40.43434 | NA | 6 | Obesity class III |
01-701-1034 | BMI | BASELINE | 40.43434 | 40.43434 | Y | 6 | Obesity class III |
01-701-1034 | BMI | WEEK 2 | 39.67406 | 40.43434 | NA | 6 | Obesity class III |
01-701-1034 | BMI | WEEK 4 | 39.48963 | 40.43434 | NA | 6 | Obesity class III |
01-701-1034 | BMI | WEEK 6 | 39.01163 | 40.43434 | NA | 6 | Obesity class III |
01-701-1034 | BMI | WEEK 8 | 38.81215 | 40.43434 | NA | 6 | Obesity class III |
CRITy
,
CRITyFL
, CRITyFN
)For deriving criterion variables (CRITy
,
CRITyFL
, CRITyFN
) {admiral}
provides derive_vars_crit_flag()
.
It ensures that they are derived in an ADaM-compliant way (see
documentation of the function for details).
In most cases the criterion depends on the parameter and in this case
the higher order function restrict_derivation()
can be useful. In the following example, the criterion flags for weight
based on percentage change in weight reduction from baseline is derived.
Additional criterion flags can be added as needed.
advs <- advs %>%
restrict_derivation(
derivation = derive_vars_crit_flag,
args = params(
condition = PCHG <= -5 & PARAMCD == "WEIGHT",
description = "Achievement of >= 5% weight reduction from baseline",
crit_nr = 1,
values_yn = TRUE,
create_numeric_flag = FALSE
),
filter = VISITNUM > 0 & PARAMCD == "WEIGHT"
) %>%
restrict_derivation(
derivation = derive_vars_crit_flag,
args = params(
condition = PCHG <= -10 & PARAMCD == "WEIGHT",
description = "Achievement of >= 10% weight reduction from baseline",
crit_nr = 2,
values_yn = TRUE,
create_numeric_flag = FALSE
),
filter = VISITNUM > 0 & PARAMCD == "WEIGHT"
)
USUBJID | PARAMCD | PCHG | CRIT1 | CRIT1FL | CRIT2 | CRIT2FL | VISIT | VISITNUM |
---|---|---|---|---|---|---|---|---|
01-701-1033 | WEIGHT | 0.000000 | Achievement of >= 5% weight reduction from baseline | N | Achievement of >= 10% weight reduction from baseline | N | BASELINE | 3 |
01-701-1034 | WEIGHT | 0.000000 | Achievement of >= 5% weight reduction from baseline | N | Achievement of >= 10% weight reduction from baseline | N | BASELINE | 3 |
01-701-1034 | WEIGHT | -9.317695 | Achievement of >= 5% weight reduction from baseline | Y | Achievement of >= 10% weight reduction from baseline | N | WEEK 16 | 10 |
01-701-1034 | WEIGHT | -9.755189 | Achievement of >= 5% weight reduction from baseline | Y | Achievement of >= 10% weight reduction from baseline | N | WEEK 20 | 11 |
01-701-1034 | WEIGHT | -11.700642 | Achievement of >= 5% weight reduction from baseline | Y | Achievement of >= 10% weight reduction from baseline | Y | WEEK 24 | 12 |
01-701-1034 | WEIGHT | -12.398771 | Achievement of >= 5% weight reduction from baseline | Y | Achievement of >= 10% weight reduction from baseline | Y | WEEK 26 | 13 |
The {admiral}
Creating
a BDS Finding ADaM vignette covers all the steps that are not shown
here, such as merging the parameter-level values, timing variables, and
analysis flags.
ADaM | Sample Code |
---|---|
ADVS | ad_advs.R |
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.