pharmaverse / admiralpeds

Admiral Package Extension for Pediatric Clinical Trials
https://pharmaverse.github.io/admiralpeds/
Apache License 2.0
13 stars 3 forks source link

New function: derive_params_growth_age - for BY AGE growth parameters #33

Closed rossfarrugia closed 5 months ago

rossfarrugia commented 6 months ago

New function:

derive_params_growth_age(
  dataset, 
  sex, 
  age, 
  age_unit, 
  meta_criteria, 
  parameter, 
  set_values_to_sds, 
  set_values_to_pctl)

Arguments:

Checks:

Derivations:

image

Example function call:

advs_wgt_age <- advs %>% 
  derive_params_growth_age(
    sex = SEX, 
    age = AAGECUR, 
    age_unit = AAGECURU, 
    meta_criteria = mymetadata,
    parameter = WGHT,
    set_values_to_sds(
      PARAMCD = “WGTASDS”,
      PARAM = “Weight-for-age Z-Score”
    ),
    set_values_to_pctl(
      PARAMCD = “WGTAPCTL”,
      PARAM = “Weight-for-age Percentile”
    )
  )

NOTE from David for BMI: CDC BMI percentiles >95 are calculated differently than this <95th percentile. Here are the 2 places that 'introduce' the new (2023) CDC calculations for BMIs > 95th percentile

  1. https://www.cdc.gov/nccdphp/dnpao/growthcharts/resources/sas.htm - (This a page that I largely wrote). You can see the big notification at the top of the screen and there's a section on 'Extended z-scores and percentiles' about halfway down the long webpage
  2. And here's a page written by CDC people in Washington (Natl Center for Health Statistics): https://stacks.cdc.gov/view/cdc/122933

We called them extended BMIz and extended BMI percentiles, but the SAS and R programs name these calculations as 'BMIz' and 'BMIp'. If someone wanted to use the old visions of the calculations to check their work done in years before 2023, the variables are named something like original_BMIz and original_BMIp

zdz2101 commented 6 months ago

@kabis-ops here is a rough work-flow of how I've started to get the appropriate metadata/join, "function-ing" it as we speak

library(admiral)
library(admiralpeds)
library(dplyr)
library(lubridate)
advs <- dm_peds %>%
  select(USUBJID, BRTHDTC, SEX) %>%
  right_join(., vs_peds, by = "USUBJID") %>%
  filter(USUBJID != "PEDS-1010") %>%
  mutate(VSDT = ymd(VSDTC),
         BRTHDT = ymd(BRTHDTC)) %>%
  derive_vars_duration(
    new_var = AGECUR_D,
    new_var_unit = CURU_D,
    start_date = BRTHDT,
    end_date = VSDT,
    out_unit = "days",
    trunc_out = FALSE
  ) %>%
  derive_vars_duration(
    new_var = AGECUR_M,
    new_var_unit = CURU_M,
    start_date = BRTHDT,
    end_date = VSDT,
    out_unit = "months",
    trunc_out = FALSE
  ) %>%
  mutate(AGECUR = ifelse(AGECUR_D >= 365.25*2, AGECUR_M, AGECUR_D),
         AGECURU = ifelse(AGECUR_D >= 365.25*2, CURU_M, CURU_D))

# metadata is in months
cdc_meta_criteria <- admiralpeds::cdc_wtage %>%
  mutate(age_unit = "months")

# metadata is in days
who_meta_criteria <- bind_rows(
  (admiralpeds::who_wt_for_age_boys %>%
     mutate(SEX = 1,
            age_unit = "days")),
  (admiralpeds::who_wt_for_age_girls %>%
     mutate(SEX = 2,
            age_unit = "days"))
) %>%
  rename(AGE = Day)

meta_criteria <- bind_rows(
  cdc_meta_criteria,
  who_meta_criteria
) %>%
  arrange(SEX, age_unit, AGE) %>%
  group_by(SEX, age_unit) %>%
  mutate(next_age = lead(AGE),
         SEX = ifelse(SEX == 1, "M", "F"))

# process metadata and join
advs_meta <- advs  %>%
  filter(VSTESTCD == "WEIGHT") %>%  # swap in appropriate PARAM statement
  left_join(., meta_criteria, by = c("SEX", "AGECURU" = "age_unit"), relationship = "many-to-many") %>%
  filter(AGE <= AGECUR & AGECUR < next_age) %>%
  mutate(SDS = ((VSSTRESN/M)^L - 1)/(L*S),
         perc = pnorm(SDS)*100) %>%
  select(-c(L, M, S, next_age)) %>%
  pivot_longer(., cols = SDS:perc, names_to = temp, values_to = "AVAL")
rossfarrugia commented 6 months ago

@zdz2101 reminder here to see the doc David sent around unit testing tips for this function so we cover a good range of boundary cases. Also around his tip on deriving for very high BMI values.