From 8d9f9d4009db62697dd8d4df6d58e79564ad7779 Mon Sep 17 00:00:00 2001 From: flunkerk Date: Mon, 11 Nov 2024 11:11:25 +0100 Subject: [PATCH] #40 Initial ADCOEQ vignette --- vignettes/adcoeq.Rmd | 244 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 vignettes/adcoeq.Rmd diff --git a/vignettes/adcoeq.Rmd b/vignettes/adcoeq.Rmd new file mode 100644 index 0000000..dc55533 --- /dev/null +++ b/vignettes/adcoeq.Rmd @@ -0,0 +1,244 @@ +--- +title: "Creating Questionnaire ADaM: Control of Eating (ADCOEQ)" +output: + rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Creating Questionnaire ADaM: Control of Eating (ADCOEQ)} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) + +library(admiraldev) +``` + +# Introduction + +Note that University of Leeds are the copyright holders of the CoEQ and the test +data included within {admiralmetabolic} as well as the ADCOEQ code are for +not-for-profit use only within {admiralmetabolic} and pharmaverse-related +examples/documentation. Any persons or companies wanting to use the CoEQ should +request a license to do so from the following [link](https://licensing.leeds.ac.uk/product/control-of-eating-questionnaire-coeq). + +**Note**: *All examples assume CDISC SDTM and/or ADaM format as input unless +otherwise specified.* + +## Required Packages + +The examples of this vignette require the following packages. + +```{r, warning=FALSE, message=FALSE} +library(dplyr) +library(tidyr) +library(tibble) +library(admiral) +library(admiralmetabolic) +``` + +## Example Data + +In this vignette we use example data for the CoEQ. +The example `QS` data (`qs_metabolic`) is included in the admiralmetabolic package. + +```{r} +qs <- admiralmetabolic::qs_metabolic +``` + +## QS: +```{r echo=FALSE} +dataset_vignette(qs) +``` + +```{r echo=FALSE} +dm <- admiralmetabolic::dm_metabolic + +adsl <- dm %>% + select(-DOMAIN) %>% + mutate(TRT01P = ARM, TRT01A = ACTARM) %>% + left_join(admiral_adsl %>% select(USUBJID, TRTSDT, TRTEDT), by = "USUBJID") +``` + +## ADSL: +```{r echo=FALSE} +dataset_vignette(adsl) +``` + +# Original Items + +The original items, i.e. the answers to the questionnaire questions, can be +handled in the same way as in a [BDS finding ADaM](bds_finding.html). For +example: + +```{r eval=TRUE} +adcoeq1 <- qs %>% + # Add ADSL variables + derive_vars_merged( + dataset_add = adsl, + new_vars = exprs(TRTSDT, TRTEDT, TRT01P, TRT01A), + by_vars = exprs(STUDYID, USUBJID) + ) %>% + # Add analysis parameter variables + mutate( + PARAMCD = QSTESTCD, + PARAM = QSTEST, + PARCAT1 = QSCAT + ) %>% + # Add timing variables + derive_vars_dt(new_vars_prefix = "A", dtc = QSDTC) %>% + derive_vars_dy(reference_date = TRTSDT, source_vars = exprs(ADT)) %>% + mutate( + AVISIT = if_else(ADT <= TRTSDT, "BASELINE", VISIT), + AVISITN = if_else(ADT <= TRTSDT, 0, VISITNUM) + ) +``` + +If the numeric values of the answers in `QSSTRESN` values are not ready to be used for deriving +scores and require transformation, it is recommended that `QSSTRESN` is kept in +the ADaM dataset for traceability, and the transformed value is stored in +`AVAL`, since that's what will be used for the score calculation. +For the CoEQ item 6 has to be handled in such way: + +```{r eval=TRUE} +adcoeq2 <- adcoeq1 %>% + # Add analysis parameter variables + mutate( + AVAL = ifelse(PARAMCD=='COEQ06', 100-QSSTRESN, QSSTRESN), + AVALC = ifelse(PARAMCD=='COEQ20', QSORRES, NA) + ) +``` + +```{r echo=FALSE} +dataset_vignette( + arrange(adcoeq2, USUBJID, PARCAT1, ADY, PARAMCD), + display_vars = exprs(USUBJID, PARAMCD, PARAM, PARCAT1, QSSTRESN, AVALC, AVAL, ADY, AVISIT) +) +``` + +We handle unscheduled visits as normal visits. For deriving visits based on +time-windows, see [Visit and Period Variables](visits_periods.html#visits). And +for flagging values to be used for analysis, see `derive_var_extreme_flag()`. + + +# Scales and Scores + +Scales and Scores are often derived as the sum or the average across a subset of +the items. +For the Control of Eating questionnaire, four subscales are derived: + +* Craving Control: Calculate average of items 9, 10, 11, 12 and 19. + +* Craving for Sweet: Calculate average of items 3, 13, 14 and 15. + +* Craving for Savoury: Calculate average of items 4, 16, 17 and 18. + +* Positive Mood: Calculate average of items 5, 7, 8 and 6 (reversed). + +These parameters can be derived by `derive_summary_records()`: +```{r eval=TRUE} +adcoeq3 <- adcoeq2 %>% + derive_summary_records( + dataset = ., + dataset_add = ., + by_vars = exprs(STUDYID, USUBJID, AVISIT, AVISITN, ADT, ADY, PARCAT1, TRTSDT, TRTEDT, TRT01P, TRT01A), + filter_add = (PARAMCD %in% c('COEQ09','COEQ10','COEQ11','COEQ12','COEQ19')), + set_values_to = exprs( + AVAL = mean(AVAL, na.rm = TRUE), + PARAMCD = "COEQCRCO", + PARAM = "COEQ - Craving Control" + ) + ) %>% + derive_summary_records( + dataset = ., + dataset_add = ., + by_vars = exprs(STUDYID, USUBJID, AVISIT, AVISITN, ADT, ADY, PARCAT1, TRTSDT, TRTEDT, TRT01P, TRT01A), + filter_add = (PARAMCD %in% c('COEQ03','COEQ13','COEQ14','COEQ15')), + set_values_to = exprs( + AVAL = mean(AVAL, na.rm = TRUE), + PARAMCD = "COEQCRSW", + PARAM = "COEQ - Craving for Sweet" + ) + ) %>% + derive_summary_records( + dataset = ., + dataset_add = ., + by_vars = exprs(STUDYID, USUBJID, AVISIT, AVISITN, ADT, ADY, PARCAT1, TRTSDT, TRTEDT, TRT01P, TRT01A), + filter_add = (PARAMCD %in% c('COEQ04','COEQ16','COEQ17','COEQ18')), + set_values_to = exprs( + AVAL = mean(AVAL, na.rm = TRUE), + PARAMCD = "COEQCRSA", + PARAM = "COEQ - Craving for Savoury" + ) + ) %>% + derive_summary_records( + dataset = ., + dataset_add = ., + by_vars = exprs(STUDYID, USUBJID, AVISIT, AVISITN, ADT, ADY, PARCAT1, TRTSDT, TRTEDT, TRT01P, TRT01A), + filter_add = (PARAMCD %in% c('COEQ05','COEQ07','COEQ08','COEQ06')), + set_values_to = exprs( + AVAL = mean(AVAL, na.rm = TRUE), + PARAMCD = "COEQPOMO", + PARAM = "COEQ - Positive Mood" + ) + ) +``` + +```{r echo=FALSE} +dataset_vignette( + arrange(adcoeq3, USUBJID, ADY, PARAMCD), + display_vars = exprs(USUBJID, PARAMCD, PARAM, AVAL, ADY, AVISIT) +) +``` + +After deriving the scores by visit, the baseline and change from baseline +variables can be derived: +```{r eval=TRUE} +adcoeq4 <- adcoeq3 %>% + # Flag baseline records (last before treatement start) + restrict_derivation( + derivation = derive_var_extreme_flag, + args = params( + by_vars = exprs(STUDYID, USUBJID, PARAMCD), + order = exprs(ADT), + new_var = ABLFL, + mode = "last" + ), + filter = !is.na(AVAL) & ADT <= TRTSDT + ) %>% + # Derive baseline and change from baseline variables + derive_var_base( + by_vars = exprs(STUDYID, USUBJID, PARAMCD), + source_var = AVAL, + new_var = BASE + ) %>% + # Calculate CHG for post-baseline records + # The decision on how to populate pre-baseline and baseline values of CHG is left to producer choice + restrict_derivation( + derivation = derive_var_chg, + filter = AVISITN > 0 + ) %>% + # Calculate PCHG for post-baseline records + # The decision on how to populate pre-baseline and baseline values of PCHG is left to producer choice + restrict_derivation( + derivation = derive_var_pchg, + filter = AVISITN > 0 + ) %>% + # Derive sequence number + derive_var_obs_number( + by_vars = exprs(STUDYID, USUBJID), + order = exprs(PARAMCD, ADT), + check_type = "error" + ) +``` + +```{r echo=FALSE} +dataset_vignette( + adcoeq4, + display_vars = exprs(USUBJID, PARAMCD, PARAM, AVISIT, ADY, AVAL, BASE, CHG, PCHG) +) +``` +