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 laboratory 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 ADLB
using
{admiral}
functions is the same. In this vignette, we focus
on common ADLB derivations in metabolic studies and avoid repeating
information and maintaining the same content in two places.
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 the ADaM dataset
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 {admiralmetabolic}
. We will utilize LB
and
ADSL
data.
Define parameter lookup table used to derive PARAMCD
,
PARAM
, and PARAMN
variables.
# Assign PARAMCD, PARAM, and PARAMN
param_lookup <- tibble::tribble(
~LBTESTCD, ~PARAMCD, ~PARAM, ~PARAMN,
"ALB", "ALB", "Albumin (g/L)", 1,
"ALP", "ALKPH", "Alkaline Phosphatase (U/L)", 2,
"AST", "AST", "Aspartate Aminotransferase (U/L)", 3,
"CHOL", "CHOLES", "Cholesterol (mmol/L)", 4,
"GGT", "GGT", "Gamma Glutamyl Transferase (U/L)", 5,
"GLUC", "GLUC", "Glucose (mmol/L)", 6,
"HBA1CHGB", "HBA1CHGB", "Hemoglobin A1C/Hemoglobin (mmol/mol)", 7,
"INSULIN", "INSULIN", "Insulin (mIU/L)", 8,
"TRIG", "TRIG", "Triglycerides (mg/dL)", 9
)
The basic parameters and timing variables can be derived similarly to
other BDS finding ADaMs. For the derivation of Glucose and Insulin, only
fasted results (where LBFAST = "Y"
) are considered. For all
other laboratory tests, the fasting status does not affect their
inclusion in the dataset at this stage.
# Define required ADSL variables for derivations
adsl_vars <- exprs(TRTSDT, TRTEDT, TRT01A, TRT01P)
adlb <- lb %>%
# Remove non-fasted GLUC and INSULIN results
filter(!(LBTESTCD %in% c("GLUC", "INSULIN") & LBFAST != "Y")) %>%
# Join ADSL with LB (need TRTSDT for ADY derivation)
derive_vars_merged(
dataset_add = adsl,
new_vars = adsl_vars,
by_vars = get_admiral_option("subject_keys")
) %>%
# Calculate ADT, ADY
derive_vars_dt(
new_vars_prefix = "A",
dtc = LBDTC
) %>%
derive_vars_dy(reference_date = TRTSDT, source_vars = exprs(ADT))
adlb <- adlb %>%
# Add PARAMCD PARAM and PARAMN - from parameter lookup table
derive_vars_merged_lookup(
dataset_add = param_lookup,
new_vars = exprs(PARAMCD, PARAM, PARAMN),
by_vars = exprs(LBTESTCD)
) %>%
## Calculate PARCAT1 PARCAT2 AVAL AVALC ANRLO ANRHI
slice_derivation(
derivation = mutate,
args = params(
PARCAT1 = LBCAT,
),
# Handle specific parameters requiring conventional units (CV)
derivation_slice(
filter = LBTESTCD %in% c("TRIG", "INSULIN"),
args = params(
PARCAT2 = "CV",
AVAL = as.numeric(LBORRES),
AVALC = NA_character_,
ANRLO = as.numeric(LBORNRLO),
ANRHI = as.numeric(LBORNRHI)
)
),
# Handle other parameters using standard units (SI)
derivation_slice(
filter = TRUE,
args = params(
PARCAT2 = "SI",
AVAL = LBSTRESN,
# Only populate AVALC if character value is non-redundant with AVAL
AVALC = if_else(
is.na(AVAL) | as.character(AVAL) != LBSTRESC,
LBSTRESC,
NA_character_
),
ANRLO = LBSTNRLO,
ANRHI = LBSTNRHI
)
)
)
#> All `LBTESTCD` are mapped.
STUDYID | USUBJID | ADT | ADY | PARAMCD | PARAM | PARAMN | PARCAT1 | PARCAT2 | AVAL | AVALC | ANRLO | ANRHI |
---|---|---|---|---|---|---|---|---|---|---|---|---|
CDISCPILOT01 | 01-701-1015 | 2013-12-26 | -7 | ALB | Albumin (g/L) | 1 | CHEMISTRY | SI | 38.00000 | NA | 33.00000 | 49.00000 |
CDISCPILOT01 | 01-701-1015 | 2013-12-26 | -7 | ALKPH | Alkaline Phosphatase (U/L) | 2 | CHEMISTRY | SI | 34.00000 | NA | 35.00000 | 115.00000 |
CDISCPILOT01 | 01-701-1015 | 2013-12-26 | -7 | AST | Aspartate Aminotransferase (U/L) | 3 | CHEMISTRY | SI | 40.00000 | NA | 9.00000 | 34.00000 |
CDISCPILOT01 | 01-701-1015 | 2013-12-26 | -7 | CHOLES | Cholesterol (mmol/L) | 4 | CHEMISTRY | SI | 5.94780 | NA | 4.03000 | 7.76000 |
CDISCPILOT01 | 01-701-1015 | 2013-12-26 | -7 | GGT | Gamma Glutamyl Transferase (U/L) | 5 | CHEMISTRY | SI | 15.00000 | NA | 5.00000 | 50.00000 |
CDISCPILOT01 | 01-701-1015 | 2013-12-26 | -7 | GLUC | Glucose (mmol/L) | 6 | CHEMISTRY | SI | 4.71835 | NA | 2.80000 | 13.90000 |
CDISCPILOT01 | 01-701-1015 | 2013-12-26 | -7 | HBA1CHGB | Hemoglobin A1C/Hemoglobin (mmol/mol) | 7 | CHEMISTRY | SI | 62.84175 | NA | 20.21865 | 38.79795 |
CDISCPILOT01 | 01-701-1015 | 2013-12-26 | -7 | INSULIN | Insulin (mIU/L) | 8 | CHEMISTRY | CV | 14.40000 | NA | 2.00000 | 25.00000 |
CDISCPILOT01 | 01-701-1015 | 2013-12-26 | -7 | TRIG | Triglycerides (mg/dL) | 9 | CHEMISTRY | CV | 111.10000 | NA | 0.00000 | 150.00000 |
CDISCPILOT01 | 01-701-1015 | 2014-01-16 | 15 | ALB | Albumin (g/L) | 1 | CHEMISTRY | SI | 39.00000 | NA | 33.00000 | 49.00000 |
Derive Analysis Visit (AVISIT
) and Analysis Visit Number
(AVISITN
).
adlb <- adlb %>%
mutate(
AVISIT = case_when(
str_detect(VISIT, "SCREEN") ~ "Baseline",
!is.na(VISIT) ~ str_to_title(VISIT),
TRUE ~ NA_character_
),
AVISITN = case_when(
AVISIT == "Baseline" ~ 0,
str_detect(VISIT, "WEEK") ~ as.integer(str_extract(VISIT, "\\d+")),
TRUE ~ NA_integer_
)
)
STUDYID | USUBJID | PARAMCD | PARAM | PARCAT1 | AVAL | ADY | AVISIT | AVISITN |
---|---|---|---|---|---|---|---|---|
CDISCPILOT01 | 01-701-1015 | ALB | Albumin (g/L) | CHEMISTRY | 38.00000 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | ALKPH | Alkaline Phosphatase (U/L) | CHEMISTRY | 34.00000 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | AST | Aspartate Aminotransferase (U/L) | CHEMISTRY | 40.00000 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | CHOLES | Cholesterol (mmol/L) | CHEMISTRY | 5.94780 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | GGT | Gamma Glutamyl Transferase (U/L) | CHEMISTRY | 15.00000 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | GLUC | Glucose (mmol/L) | CHEMISTRY | 4.71835 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | HBA1CHGB | Hemoglobin A1C/Hemoglobin (mmol/mol) | CHEMISTRY | 62.84175 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | INSULIN | Insulin (mIU/L) | CHEMISTRY | 14.40000 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | TRIG | Triglycerides (mg/dL) | CHEMISTRY | 111.10000 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | ALB | Albumin (g/L) | CHEMISTRY | 39.00000 | 15 | Week 2 | 2 |
For deriving visits based on time-windows, see {admiral}
Visit
and Period Variables.
In addition to the core ADLB variables, several metabolic parameters and scores will be derived based on laboratory data and vital signs. These derivations include:
Fatty Liver Index (FLI): Derived from triglycerides (mg/dL), GGT (U/L), BMI (kg/m2), and waist circumference (cm). \[ FLI = \left[\frac{\exp(\lambda)}{1 + \exp(\lambda)}\right] \times 100 \] where \[ \lambda = 0.953 \times \ln (\text{triglycerides}) + 0.139 \times BMI + 0.718 \times \ln (GGT) + 0.053 \times \text{waist circumference} – 15.745. \] FLI is interpreted as a score between 0 and 100, where higher values indicate a worse condition.
Homeostasis Model Assessment – Insulin Resistance (HOMA-IR): Calculated from fasting plasma glucose (mmol/L) and fasting plasma insulin (mIU/L). \[ \text{HOMA-IR} = \frac{FPI \times FPG}{22.5}. \] An alternative formula is used when fasting plasma glucose is assessed in mg/dL: \[ \text{HOMA-IR} = \frac{FPI \times FPG}{405}. \]
To derive these parameters and scores, the following variables will be needed:
In this section, we will merge relevant variables needed to derive metabolic parameter from the ADVS (Analysis Dataset for Vital Signs) dataset into the ADLB dataset. This is necessary to include variables such as BMI and Waist Circumference, which are required for the derivation of FLI score parameter in subsequent section.
# Load ADVS dataset (assuming it has been created by ad_advs.R)
admiralmetabolic_advs <- admiralmetabolic::admiralmetabolic_advs
advs <- convert_blanks_to_na(admiralmetabolic_advs)
# Merge BMI and WSTCIR from ADVS to ADLB based on subject and date
adlb <- adlb %>%
derive_vars_transposed(
advs,
by_vars = exprs(!!!get_admiral_option("subject_keys"), ADT),
key_var = PARAMCD,
value_var = AVAL,
filter = PARAMCD %in% c("BMI", "WSTCIR")
)
Please note that in this example we merge on ADT, but it is also possible to merge on AVISIT or other windowing algorithms specified in the statistical analysis plan.
STUDYID | USUBJID | PARAMCD | PARAM | AVAL | ADT | ADY | AVISIT | AVISITN | BMI | WSTCIR |
---|---|---|---|---|---|---|---|---|---|---|
CDISCPILOT01 | 01-701-1015 | ALB | Albumin (g/L) | 38.00000 | 2013-12-26 | -7 | Baseline | 0 | 38.10500 | 99 |
CDISCPILOT01 | 01-701-1015 | ALKPH | Alkaline Phosphatase (U/L) | 34.00000 | 2013-12-26 | -7 | Baseline | 0 | 38.10500 | 99 |
CDISCPILOT01 | 01-701-1015 | AST | Aspartate Aminotransferase (U/L) | 40.00000 | 2013-12-26 | -7 | Baseline | 0 | 38.10500 | 99 |
CDISCPILOT01 | 01-701-1015 | CHOLES | Cholesterol (mmol/L) | 5.94780 | 2013-12-26 | -7 | Baseline | 0 | 38.10500 | 99 |
CDISCPILOT01 | 01-701-1015 | GGT | Gamma Glutamyl Transferase (U/L) | 15.00000 | 2013-12-26 | -7 | Baseline | 0 | 38.10500 | 99 |
CDISCPILOT01 | 01-701-1015 | GLUC | Glucose (mmol/L) | 4.71835 | 2013-12-26 | -7 | Baseline | 0 | 38.10500 | 99 |
CDISCPILOT01 | 01-701-1015 | HBA1CHGB | Hemoglobin A1C/Hemoglobin (mmol/mol) | 62.84175 | 2013-12-26 | -7 | Baseline | 0 | 38.10500 | 99 |
CDISCPILOT01 | 01-701-1015 | INSULIN | Insulin (mIU/L) | 14.40000 | 2013-12-26 | -7 | Baseline | 0 | 38.10500 | 99 |
CDISCPILOT01 | 01-701-1015 | TRIG | Triglycerides (mg/dL) | 111.10000 | 2013-12-26 | -7 | Baseline | 0 | 38.10500 | 99 |
CDISCPILOT01 | 01-701-1015 | ALB | Albumin (g/L) | 39.00000 | 2014-01-16 | 15 | Week 2 | 2 | 38.53219 | 100 |
This part describes how to calculate the Homeostasis Model Assessment – Insulin Resistance (HOMA-IR) index from fasting plasma glucose and fasting plasma insulin. This derivation does not require merging data from other datasets.
# Derive HOMA-IR using derive_param_computed
adlb <- adlb %>%
derive_param_computed(
by_vars = exprs(!!!get_admiral_option("subject_keys"), AVISIT, AVISITN, ADT, ADY, !!!adsl_vars),
parameters = c("INSULIN", "GLUC"),
set_values_to = exprs(
AVAL = AVAL.INSULIN * AVAL.GLUC / 22.5,
PARAMCD = "HOMAIR",
PARAM = "Homeostasis Model Assessment - Insulin Resistance",
PARAMN = 10
)
)
STUDYID | USUBJID | PARAMCD | PARAM | AVAL | ADY | AVISIT | AVISITN |
---|---|---|---|---|---|---|---|
CDISCPILOT01 | 01-701-1015 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 3.019744 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 8.289493 | 15 | Week 2 | 2 |
CDISCPILOT01 | 01-701-1015 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 5.606263 | 42 | Week 6 | 6 |
CDISCPILOT01 | 01-701-1015 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 4.369747 | 63 | Week 8 | 8 |
CDISCPILOT01 | 01-701-1015 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 6.675262 | 84 | Week 12 | 12 |
CDISCPILOT01 | 01-701-1015 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 8.635382 | 126 | Week 16 | 16 |
CDISCPILOT01 | 01-701-1015 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 3.495403 | 140 | Week 20 | 20 |
CDISCPILOT01 | 01-701-1015 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 6.354785 | 168 | Week 24 | 24 |
CDISCPILOT01 | 01-701-1015 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 6.854622 | 182 | Week 26 | 26 |
CDISCPILOT01 | 01-701-1023 | HOMAIR | Homeostasis Model Assessment - Insulin Resistance | 6.513173 | -14 | Baseline | 0 |
To obtain the FLI score parameter, we’ll utilize triglycerides, GGT, BMI, and waist circumference. Note that this derivation requires merging data from the ADVS dataset (BMI and Waist Circumference), as demonstrated in the previous section. FLI is provided here as an example; users can derive other metabolic scores like HSI, NAFLD, and others using the same logic and required input variables.
# Derive FLI using derive_param_computed
adlb <- adlb %>%
derive_param_computed(
by_vars = exprs(!!!get_admiral_option("subject_keys"), AVISIT, AVISITN, ADT, ADY, BMI, WSTCIR, !!!adsl_vars),
parameters = c("TRIG", "GGT"),
set_values_to = exprs(
AVAL = {
lambda <- 0.953 * log(AVAL.TRIG) + 0.139 * BMI + 0.718 * log(AVAL.GGT) + 0.053 * WSTCIR - 15.745
(exp(lambda) / (1 + exp(lambda))) * 100
},
PARAMCD = "FLI",
PARAM = "Fatty Liver Index",
PARAMN = 11
)
)
adlb <- adlb %>%
arrange(!!!get_admiral_option("subject_keys"), ADT, PARAMN) # Arrange for consistency
STUDYID | USUBJID | PARAMCD | PARAM | AVAL | ADY | AVISIT | AVISITN |
---|---|---|---|---|---|---|---|
CDISCPILOT01 | 01-701-1015 | FLI | Fatty Liver Index | 77.41712 | -7 | Baseline | 0 |
CDISCPILOT01 | 01-701-1015 | FLI | Fatty Liver Index | 52.97118 | 15 | Week 2 | 2 |
CDISCPILOT01 | 01-701-1015 | FLI | Fatty Liver Index | 83.46849 | 42 | Week 6 | 6 |
CDISCPILOT01 | 01-701-1015 | FLI | Fatty Liver Index | 81.29596 | 63 | Week 8 | 8 |
CDISCPILOT01 | 01-701-1015 | FLI | Fatty Liver Index | 69.50608 | 84 | Week 12 | 12 |
CDISCPILOT01 | 01-701-1015 | FLI | Fatty Liver Index | 51.45346 | 126 | Week 16 | 16 |
CDISCPILOT01 | 01-701-1015 | FLI | Fatty Liver Index | 91.01194 | 140 | Week 20 | 20 |
CDISCPILOT01 | 01-701-1015 | FLI | Fatty Liver Index | 93.15697 | 168 | Week 24 | 24 |
CDISCPILOT01 | 01-701-1015 | FLI | Fatty Liver Index | 88.77355 | 182 | Week 26 | 26 |
CDISCPILOT01 | 01-701-1023 | FLI | Fatty Liver Index | 73.64499 | -14 | Baseline | 0 |
The {admiral}
Creating
a BDS Finding ADaM vignette describes further steps, including how
to calculate baseline and change from baseline variables, add analysis
flags (e.g., ANL01FL
), handle reference ranges,
categorizations, and other common ADLB requirements.
ADaM | Sample Code |
---|---|
ADLB | ad_adlb.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.