From 97b58c77e0552cee784fa0a6a93ff5d13af35483 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 3 Sep 2024 14:55:11 +0000 Subject: [PATCH 01/83] initial draft --- R/derive_vars_cat.R | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 R/derive_vars_cat.R diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R new file mode 100644 index 000000000..6e187af7c --- /dev/null +++ b/R/derive_vars_cat.R @@ -0,0 +1,50 @@ +#' Derive pair of variables +#' +#' +#' @param dataset +#' @param definition +#' +#' @return +#' @export +#' +#' @examples +#' +#' advs <- tibble::tribble( +#' ~USUBJID, ~PARAMCD, ~AVAL, +#' "01", "HEIGHT", 150, +#' "02", "HEIGHT", 135, +#' "03", "HEIGHT", 145 +#' ) +#' +#' define_tibble <- tribble( +#' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, +#' expr(AVAL > 140), ">140 cm", 1, "extra1", +#' expr(AVAL <= 140), "<=140 cm", 2, "extra2" +#' ) +#' +#' +#' derive_vars_cat(dataset = advs, definition = define_tibble) %>% print() + +derive_vars_cat <- function(dataset, + definition) { + # assertions (waiting for feedback first) + + # extract new variable names + new_col_names <- names(expr_list)[!names(expr_list)=="condition"] + + # (re)apply the function for each new variable name and iteratively derive the categories + new_dataset <- reduce(new_col_names, function(.data, col_name) { + # extract conditions + condition <- definition[["condition"]] # could also be outside of the function + # extract values + values <- definition[[col_name]] + + .data %>% + mutate(!!sym(col_name) := eval(rlang::call2( + "case_when", + !!!map2(condition, values, ~ expr(!!.x ~ !!.y)) + ))) + }, .init = dataset) + + return(new_dataset) +} From b79a5585081e10db0740ecc1fa2a02fba73827e4 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 5 Sep 2024 12:40:30 +0000 Subject: [PATCH 02/83] now using exprs --- R/derive_vars_cat.R | 64 ++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 6e187af7c..032d127e9 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -2,42 +2,64 @@ #' #' #' @param dataset -#' @param definition +#' @param definition of condition and values defined as `exprs()` object. +#' e.g. exprs(~condition, ~AVALCAT1, ~AVALCA1N +#' AVAL >= 140, ">=140 cm", 1, +#' AVAL < 140, "<140 cm", 2) #' #' @return #' @export #' #' @examples #' -#' advs <- tibble::tribble( -#' ~USUBJID, ~PARAMCD, ~AVAL, -#' "01", "HEIGHT", 150, -#' "02", "HEIGHT", 135, -#' "03", "HEIGHT", 145 -#' ) -#' -#' define_tibble <- tribble( -#' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, -#' expr(AVAL > 140), ">140 cm", 1, "extra1", -#' expr(AVAL <= 140), "<=140 cm", 2, "extra2" -#' ) -#' -#' -#' derive_vars_cat(dataset = advs, definition = define_tibble) %>% print() +# advs <- tibble::tribble( +# ~USUBJID, ~PARAMCD, ~AVAL, +# "01", "HEIGHT", 150, +# "02", "HEIGHT", 135, +# "03", "HEIGHT", 145 +# ) + +# advs <- pharmaverseadam::advs +# +# definition <- exprs( +# ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, +# VSTESTCD == "HEIGHT" & AVAL > 140, ">140 cm", 1, "extra1", +# VSTESTCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 2, "extra2" +# ) +# +# +# definition <- exprs( +# ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, +# VSTESTCD == "HEIGHT" & AVAL >= 150, ">=150 cm", 1, "extra1", +# VSTESTCD == "HEIGHT" & AVAL > 140 & AVAL < 150, "[140 cm, 150 cm]", 2, "extra2", +# VSTESTCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 3, "extra3" +# ) +# + +# derive_vars_cat(dataset = advs, definition = definition) %>% select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) %>% filter(VSTESTCD == "HEIGHT") derive_vars_cat <- function(dataset, definition) { - # assertions (waiting for feedback first) + # assertions + assert_data_frame(dataset) + assert_expr_list(definition) + assert_data_frame(dataset, required_vars = admiraldev::extract_vars(definition) %>% unique()) - # extract new variable names - new_col_names <- names(expr_list)[!names(expr_list)=="condition"] + # transform definition to tibble + names(definition) <- NULL + definition <- tibble::tribble(!!!definition) + assert_data_frame(definition, required_vars = exprs(condition)) + + + # extract new variable names and conditions + new_col_names <- names(definition)[!names(definition)=="condition"] + condition <- definition[["condition"]] # could also be outside of the function # (re)apply the function for each new variable name and iteratively derive the categories new_dataset <- reduce(new_col_names, function(.data, col_name) { # extract conditions - condition <- definition[["condition"]] # could also be outside of the function - # extract values values <- definition[[col_name]] + # extract values .data %>% mutate(!!sym(col_name) := eval(rlang::call2( From 5d2b1bc3b3660764f23072a1cb9daa92155f6eb5 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 5 Sep 2024 14:44:24 +0000 Subject: [PATCH 03/83] added unit tests --- tests/testthat/_snaps/derive_vars_cat.md | 136 +++++++++++++++++ tests/testthat/test-derive_vars_cat.R | 177 +++++++++++++++++++++++ 2 files changed, 313 insertions(+) create mode 100644 tests/testthat/_snaps/derive_vars_cat.md create mode 100644 tests/testthat/test-derive_vars_cat.R diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md new file mode 100644 index 000000000..f117a99af --- /dev/null +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -0,0 +1,136 @@ +# derive_vars_cat Test 1: Basic functionality with advs dataset + + Code + result + Output + # A tibble: 254 x 5 + USUBJID VSTEST AVAL AVALCAT1 AVALCA1N + + 1 01-701-1015 Height 147. <160 2 + 2 01-701-1023 Height 163. >=160 1 + 3 01-701-1028 Height 178. >=160 1 + 4 01-701-1033 Height 175. >=160 1 + 5 01-701-1034 Height 155. <160 2 + 6 01-701-1047 Height 149. <160 2 + 7 01-701-1097 Height 169. >=160 1 + 8 01-701-1111 Height 158. <160 2 + 9 01-701-1115 Height 182. >=160 1 + 10 01-701-1118 Height 180. >=160 1 + # i 244 more rows + +# derive_vars_cat Test 2: Error when dataset is not a dataframe + + Argument `dataset` must be class , but is a list. + +# derive_vars_cat Test 3: Error when definition is not an exprs object + + Must specify at least one column using the `~name` syntax. + +# derive_vars_cat Test 4: Error when required columns are missing from dataset + + Required variable `VSTEST` is missing in `dataset` + +# derive_vars_cat Test 5: Correct behavior when no conditions are met + + Code + result + Output + # A tibble: 254 x 5 + USUBJID VSTEST AVAL AVALCAT1 AVALCA1N + + 1 01-701-1015 Height 147. NA + 2 01-701-1023 Height 163. NA + 3 01-701-1028 Height 178. NA + 4 01-701-1033 Height 175. NA + 5 01-701-1034 Height 155. NA + 6 01-701-1047 Height 149. NA + 7 01-701-1097 Height 169. NA + 8 01-701-1111 Height 158. NA + 9 01-701-1115 Height 182. NA + 10 01-701-1118 Height 180. NA + # i 244 more rows + +# derive_vars_cat Test 6: Overlapping conditions handled correctly + + Code + result + Output + # A tibble: 254 x 5 + USUBJID VSTEST AVAL AVALCAT1 AVALCA1N + + 1 01-701-1015 Height 147. NA + 2 01-701-1023 Height 163. >=160 1 + 3 01-701-1028 Height 178. >=160 1 + 4 01-701-1033 Height 175. >=160 1 + 5 01-701-1034 Height 155. NA + 6 01-701-1047 Height 149. NA + 7 01-701-1097 Height 169. >=160 1 + 8 01-701-1111 Height 158. >155 2 + 9 01-701-1115 Height 182. >=160 1 + 10 01-701-1118 Height 180. >=160 1 + # i 244 more rows + +# derive_vars_cat Test 7: Handles missing values in dataset correctly + + Code + result + Output + # A tibble: 254 x 5 + USUBJID VSTEST AVAL AVALCAT1 AVALCA1N + + 1 01-701-1015 Height NA NA + 2 01-701-1023 Height NA NA + 3 01-701-1028 Height NA NA + 4 01-701-1033 Height NA NA + 5 01-701-1034 Height NA NA + 6 01-701-1047 Height 149. <160 2 + 7 01-701-1097 Height 169. >=160 1 + 8 01-701-1111 Height 158. <160 2 + 9 01-701-1115 Height 182. >=160 1 + 10 01-701-1118 Height 180. >=160 1 + # i 244 more rows + +# derive_vars_cat Test 8: Error when condition is missing from exprs() definition object + + Required variable `condition` is missing in `definition` + +# derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and BILI) + + Code + result + Output + # A tibble: 2,493 x 5 + USUBJID VSTEST AVAL AVALCAT1 AVALCA1N + + 1 01-701-1015 Height 147. Height < 160 2 + 2 01-701-1015 Weight 54.0 Weight < 66.68 4 + 3 01-701-1015 Weight 54.4 Weight < 66.68 4 + 4 01-701-1015 Weight 53.1 Weight < 66.68 4 + 5 01-701-1015 Weight 54.0 Weight < 66.68 4 + 6 01-701-1015 Weight 53.1 Weight < 66.68 4 + 7 01-701-1015 Weight 53.1 Weight < 66.68 4 + 8 01-701-1015 Weight 53.1 Weight < 66.68 4 + 9 01-701-1015 Weight 53.1 Weight < 66.68 4 + 10 01-701-1015 Weight 53.1 Weight < 66.68 4 + # i 2,483 more rows + +# derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset + + Code + result + Output + # A tibble: 254 x 6 + USUBJID VSTEST AVAL AVALCAT1 AVALCA1N extra_var + + 1 01-701-1015 Height 147. <160 2 FALSE + 2 01-701-1023 Height 163. >=160 1 TRUE + 3 01-701-1028 Height 178. >=160 1 TRUE + 4 01-701-1033 Height 175. >=160 1 TRUE + 5 01-701-1034 Height 155. <160 2 FALSE + 6 01-701-1047 Height 149. <160 2 FALSE + 7 01-701-1097 Height 169. >=160 1 TRUE + 8 01-701-1111 Height 158. <160 2 FALSE + 9 01-701-1115 Height 182. >=160 1 TRUE + 10 01-701-1118 Height 180. >=160 1 TRUE + # i 244 more rows + diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R new file mode 100644 index 000000000..bd877a3bb --- /dev/null +++ b/tests/testthat/test-derive_vars_cat.R @@ -0,0 +1,177 @@ +library(testthat) +library(dplyr) +library(pharmaverseadam) + +# Load the advs dataset +advs <- pharmaverseadam::advs + +## Test 1: Basic functionality with advs dataset ---- +test_that("derive_vars_cat Test 1: Basic functionality with advs dataset", { + # Define the condition and categories + definition <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL >= 160, ">=160", 1, + VSTEST == "Height" & AVAL < 160, "<160", 2 + ) + + result <- derive_vars_cat(advs, definition) %>% + select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) %>% + filter(VSTEST == "Height") + + expect_snapshot(result) +}) + +## Test 2: Error when dataset is not a dataframe ---- +test_that("derive_vars_cat Test 2: Error when dataset is not a dataframe", { + # Define the condition and categories + definition <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL >= 160, ">=160", 1, + VSTEST == "Height" & AVAL < 160, "<160", 2 + ) + + # Snapshot the error message + expect_snapshot_error( + derive_vars_cat(list(1, 2, 3), definition) + ) +}) + +## Test 3: Error when definition is not an exprs object ---- +test_that("derive_vars_cat Test 3: Error when definition is not an exprs object", { + # Snapshot the error message + expect_snapshot_error( + derive_vars_cat(advs, list(condition = "Height", AVALCAT1 = 1)) + ) +}) + +## Test 4: Error when required columns are missing from dataset ---- +test_that("derive_vars_cat Test 4: Error when required columns are missing from dataset", { + # Define the condition and categories (without VSTEST in the dataset) + definition <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL >= 160, ">=160", 1, + VSTEST == "Height" & AVAL < 160, "<160", 2 + ) + + # Remove VSTEST column from dataset + advs_missing_col <- advs %>% select(-VSTEST) + + # Snapshot the error message + expect_snapshot_error( + derive_vars_cat(advs_missing_col, definition) + ) +}) + +## Test 5: Correct behavior when no conditions are met ---- +test_that("derive_vars_cat Test 5: Correct behavior when no conditions are met", { + # Define conditions that do not match any rows + definition <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL < 0, "<0", 1 + ) + + result <- derive_vars_cat(advs, definition) %>% + filter(VSTEST == "Height") %>% + select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) + + expect_snapshot(result) +}) + +## Test 6: Overlapping conditions handled correctly ---- +test_that("derive_vars_cat Test 6: Overlapping conditions handled correctly", { + # Define overlapping conditions + definition <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL >= 160, ">=160", 1, + VSTEST == "Height" & AVAL > 155, ">155", 2 + ) + + result <- derive_vars_cat(advs, definition) %>% + select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) %>% + filter(VSTEST == "Height") + + expect_snapshot(result) +}) + +## Test 7: Handles missing values in dataset correctly ---- +test_that("derive_vars_cat Test 7: Handles missing values in dataset correctly", { + # Introduce missing values in AVAL + advs_missing <- advs %>% filter(VSTEST == "Height") + advs_missing$AVAL[1:5] <- NA + + # Define the condition and categories + definition <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL >= 160, ">=160", 1, + VSTEST == "Height" & AVAL < 160, "<160", 2 + ) + + result <- derive_vars_cat(advs_missing, definition) %>% + select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) + + expect_snapshot(result) +}) + +## too slow, not sure if necessary. +# test_that("Large dataset is handled efficiently", { +# # Create a large dataset by replicating advs +# large_advs <- bind_rows(replicate(1000, advs, simplify = FALSE)) +# +# # Define the condition and categories +# definition <- exprs( +# ~condition, ~AVALCAT1, ~AVALCA1N, +# VSTEST == "Height" & AVAL >= 160, ">=160", 1, +# VSTEST == "Height" & AVAL < 160, "<160", 2 +# ) +# +# expect_snapshot(derive_vars_cat(large_advs, definition)) +# }) + +## Test 8: Error when condition is missing from exprs() definition object ---- +test_that("derive_vars_cat Test 8: Error when condition is missing from exprs() definition object", { + # Define the condition but omit the 'condition' column from the definition + definition <- exprs( + ~AVALCAT1, ~AVALCA1N, + ">=160", 1, + "<160", 2 + ) + + # Snapshot the error message + expect_snapshot_error( + derive_vars_cat(advs, definition) + ) +}) + +## Test 9: Conditions for multiple VSTESTs (Height and BILI) ---- +test_that("derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and BILI)", { + # Define conditions for two different VSTEST values: Height and BILI + definition <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL >= 160, "Height >= 160", 1, + VSTEST == "Height" & AVAL < 160, "Height < 160", 2, + VSTEST == "Weight" & AVAL >= 66.68, "Weight >= 66.68", 3, + VSTEST == "Weight" & AVAL < 66.68, "Weight < 66.68", 4 + ) + + result <- derive_vars_cat(advs, definition) %>% + select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) %>% + filter(VSTEST %in% c("Height", "Weight")) + + expect_snapshot(result) +}) + +## Test 10: Adding an extra variable (flag) to the dataset ---- +test_that("derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset", { + # Define conditions and add a third variable (flag) that is TRUE or FALSE + definition <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, ~extra_var, + VSTEST == "Height" & AVAL >= 160, ">=160", 1, TRUE, + VSTEST == "Height" & AVAL < 160, "<160", 2, FALSE + ) + + result <- derive_vars_cat(advs, definition) %>% + select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N, extra_var) %>% + filter(VSTEST == "Height") + + expect_snapshot(result) +}) From 95c1cc28d8ca1bcfa4286895ffe94a4458b59d59 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 5 Sep 2024 14:49:18 +0000 Subject: [PATCH 04/83] added manual and namespace --- NAMESPACE | 1 + R/derive_vars_cat.R | 48 +++++++++++---------------- man/derive_vars_cat.Rd | 42 +++++++++++++++++++++++ tests/testthat/test-derive_vars_cat.R | 4 --- 4 files changed, 62 insertions(+), 33 deletions(-) create mode 100644 man/derive_vars_cat.Rd diff --git a/NAMESPACE b/NAMESPACE index 8e9b12453..9bab92b1c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -100,6 +100,7 @@ export(derive_var_trtdurd) export(derive_var_trtemfl) export(derive_vars_aage) export(derive_vars_atc) +export(derive_vars_cat) export(derive_vars_computed) export(derive_vars_crit_flag) export(derive_vars_dt) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 032d127e9..fca6791fb 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -1,42 +1,32 @@ #' Derive pair of variables -#' -#' -#' @param dataset +#' @param dataset data frame containing the variables specified in the conditions #' @param definition of condition and values defined as `exprs()` object. #' e.g. exprs(~condition, ~AVALCAT1, ~AVALCA1N #' AVAL >= 140, ">=140 cm", 1, #' AVAL < 140, "<140 cm", 2) #' -#' @return +#' @return data frame #' @export #' #' @examples #' -# advs <- tibble::tribble( -# ~USUBJID, ~PARAMCD, ~AVAL, -# "01", "HEIGHT", 150, -# "02", "HEIGHT", 135, -# "03", "HEIGHT", 145 -# ) - -# advs <- pharmaverseadam::advs -# -# definition <- exprs( -# ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, -# VSTESTCD == "HEIGHT" & AVAL > 140, ">140 cm", 1, "extra1", -# VSTESTCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 2, "extra2" -# ) -# -# -# definition <- exprs( -# ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, -# VSTESTCD == "HEIGHT" & AVAL >= 150, ">=150 cm", 1, "extra1", -# VSTESTCD == "HEIGHT" & AVAL > 140 & AVAL < 150, "[140 cm, 150 cm]", 2, "extra2", -# VSTESTCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 3, "extra3" -# ) -# - -# derive_vars_cat(dataset = advs, definition = definition) %>% select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) %>% filter(VSTESTCD == "HEIGHT") +#' advs <- tibble::tribble( +#' ~USUBJID, ~PARAMCD, ~AVAL, +#' "01", "HEIGHT", 150, +#' "02", "HEIGHT", 135, +#' "03", "HEIGHT", 145 +#' ) +#' advs <- pharmaverseadam::advs +#' +#' definition <- exprs( +#' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, +#' VSTESTCD == "HEIGHT" & AVAL > 140, ">140 cm", 1, "extra1", +#' VSTESTCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 2, "extra2" +#' ) +#' +#' derive_vars_cat(dataset = advs %>% filter(VSTESTCD == "HEIGHT"), +#' definition = definition) %>% +#' select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) derive_vars_cat <- function(dataset, definition) { diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd new file mode 100644 index 000000000..0bc25869f --- /dev/null +++ b/man/derive_vars_cat.Rd @@ -0,0 +1,42 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/derive_vars_cat.R +\name{derive_vars_cat} +\alias{derive_vars_cat} +\title{Derive pair of variables} +\usage{ +derive_vars_cat(dataset, definition) +} +\arguments{ +\item{dataset}{data frame containing the variables specified in the conditions} + +\item{definition}{of condition and values defined as \code{exprs()} object. +e.g. exprs(~condition, ~AVALCAT1, ~AVALCA1N +AVAL >= 140, ">=140 cm", 1, +AVAL < 140, "<140 cm", 2)} +} +\value{ +data frame +} +\description{ +Derive pair of variables +} +\examples{ + +advs <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~AVAL, + "01", "HEIGHT", 150, + "02", "HEIGHT", 135, + "03", "HEIGHT", 145 +) +advs <- pharmaverseadam::advs + +definition <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, + VSTESTCD == "HEIGHT" & AVAL > 140, ">140 cm", 1, "extra1", + VSTESTCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 2, "extra2" +) + +derive_vars_cat(dataset = advs \%>\% filter(VSTESTCD == "HEIGHT"), + definition = definition) \%>\% + select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) +} diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index bd877a3bb..03587da2e 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -1,7 +1,3 @@ -library(testthat) -library(dplyr) -library(pharmaverseadam) - # Load the advs dataset advs <- pharmaverseadam::advs From f1f19842ed9a6938ca8192c85a29d63c82d96f50 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 5 Sep 2024 19:04:43 +0000 Subject: [PATCH 05/83] lint and style --- R/derive_vars_cat.R | 14 ++++---------- inst/WORDLIST | 6 +++--- tests/testthat/test-derive_vars_cat.R | 17 +---------------- 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index fca6791fb..e0c4abf21 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -10,21 +10,15 @@ #' #' @examples #' -#' advs <- tibble::tribble( -#' ~USUBJID, ~PARAMCD, ~AVAL, -#' "01", "HEIGHT", 150, -#' "02", "HEIGHT", 135, -#' "03", "HEIGHT", 145 -#' ) #' advs <- pharmaverseadam::advs #' #' definition <- exprs( #' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, -#' VSTESTCD == "HEIGHT" & AVAL > 140, ">140 cm", 1, "extra1", -#' VSTESTCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 2, "extra2" +#' VSTESTCD == "Height" & AVAL > 140, ">140 cm", 1, "extra1", +#' VSTESTCD == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" #' ) #' -#' derive_vars_cat(dataset = advs %>% filter(VSTESTCD == "HEIGHT"), +#' derive_vars_cat(dataset = advs %>% filter(VSTESTCD == "Height"), #' definition = definition) %>% #' select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) @@ -42,7 +36,7 @@ derive_vars_cat <- function(dataset, # extract new variable names and conditions - new_col_names <- names(definition)[!names(definition)=="condition"] + new_col_names <- names(definition) [!names(definition) == "condition"] condition <- definition[["condition"]] # could also be outside of the function # (re)apply the function for each new variable name and iteratively derive the categories diff --git a/inst/WORDLIST b/inst/WORDLIST index af85510d1..961cf3606 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -30,6 +30,8 @@ ASTDTM ATC ATOXGR AVAL +AVALCA +AVALCAT Abercrombie Akinyi Alanine @@ -170,10 +172,10 @@ Nom Nonfasting O'Reilly OCCDS +ORCID Ojesh Omnes Ondrej -ORCID PARAM PARAMCD PARAMN @@ -310,14 +312,12 @@ pre prev prm quosures -Rothstein recoded renv repo reproducibility rlang roche -Rothstein roxygen scalable signif diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index 03587da2e..3876df15a 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -108,23 +108,8 @@ test_that("derive_vars_cat Test 7: Handles missing values in dataset correctly", expect_snapshot(result) }) -## too slow, not sure if necessary. -# test_that("Large dataset is handled efficiently", { -# # Create a large dataset by replicating advs -# large_advs <- bind_rows(replicate(1000, advs, simplify = FALSE)) -# -# # Define the condition and categories -# definition <- exprs( -# ~condition, ~AVALCAT1, ~AVALCA1N, -# VSTEST == "Height" & AVAL >= 160, ">=160", 1, -# VSTEST == "Height" & AVAL < 160, "<160", 2 -# ) -# -# expect_snapshot(derive_vars_cat(large_advs, definition)) -# }) - ## Test 8: Error when condition is missing from exprs() definition object ---- -test_that("derive_vars_cat Test 8: Error when condition is missing from exprs() definition object", { +test_that("derive_vars_cat Test 8: Error when condition is missing from `definition`", { # Define the condition but omit the 'condition' column from the definition definition <- exprs( ~AVALCAT1, ~AVALCA1N, From dd38c99a5fd1546f749b0195475cb8e0573d1eb9 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 5 Sep 2024 19:08:12 +0000 Subject: [PATCH 06/83] udpate manual --- man/derive_vars_cat.Rd | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 0bc25869f..5eddbc680 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -22,21 +22,15 @@ Derive pair of variables } \examples{ -advs <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~AVAL, - "01", "HEIGHT", 150, - "02", "HEIGHT", 135, - "03", "HEIGHT", 145 -) advs <- pharmaverseadam::advs definition <- exprs( ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, - VSTESTCD == "HEIGHT" & AVAL > 140, ">140 cm", 1, "extra1", - VSTESTCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 2, "extra2" + VSTESTCD == "Height" & AVAL > 140, ">140 cm", 1, "extra1", + VSTESTCD == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" ) -derive_vars_cat(dataset = advs \%>\% filter(VSTESTCD == "HEIGHT"), +derive_vars_cat(dataset = advs \%>\% filter(VSTESTCD == "Height"), definition = definition) \%>\% select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) } From 8b586504258b2bae189a5ecaca39885f967d5b84 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 5 Sep 2024 19:44:20 +0000 Subject: [PATCH 07/83] styler --- R/derive_vars_cat.R | 39 +++++++++++++---- tests/testthat/_snaps/derive_vars_cat.md | 54 +++++++++++++----------- tests/testthat/test-derive_vars_cat.R | 24 ++++++++++- 3 files changed, 83 insertions(+), 34 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index e0c4abf21..9b763bc0a 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -10,18 +10,41 @@ #' #' @examples #' -#' advs <- pharmaverseadam::advs +#' advs <- tibble::tribble( +#' ~USUBJID, ~VSTEST, ~AVAL, +#' "01-701-1015", "Height", 147.32, +#' "01-701-1015", "Weight", 53.98, +#' "01-701-1023", "Height", 162.56, +#' "01-701-1023", "Weight", 78.47, +#' "01-701-1028", "Height", 177.8, +#' "01-701-1028", "Weight", 98.88, +#' "01-701-1033", "Height", 175.26, +#' "01-701-1033", "Weight", 88.45, +#' "01-701-1034", "Height", 154.94, +#' "01-701-1034", "Weight", 63.5, +#' "01-701-1047", "Height", 148.59, +#' "01-701-1047", "Weight", 66.23, +#' "01-701-1097", "Height", 168.91, +#' "01-701-1097", "Weight", 78.02, +#' "01-701-1111", "Height", 158.24, +#' "01-701-1111", "Weight", 60.33, +#' "01-701-1115", "Height", 181.61, +#' "01-701-1115", "Weight", 78.7, +#' "01-701-1118", "Height", 180.34, +#' "01-701-1118", "Weight", 71.67 +#' ) #' #' definition <- exprs( -#' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, -#' VSTESTCD == "Height" & AVAL > 140, ">140 cm", 1, "extra1", -#' VSTESTCD == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" +#' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, +#' VSTESTCD == "Height" & AVAL > 140, ">140 cm", 1, "extra1", +#' VSTESTCD == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" #' ) #' -#' derive_vars_cat(dataset = advs %>% filter(VSTESTCD == "Height"), -#' definition = definition) %>% +#' derive_vars_cat( +#' dataset = advs %>% filter(VSTESTCD == "Height"), +#' definition = definition +#' ) %>% #' select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) - derive_vars_cat <- function(dataset, definition) { # assertions @@ -36,7 +59,7 @@ derive_vars_cat <- function(dataset, # extract new variable names and conditions - new_col_names <- names(definition) [!names(definition) == "condition"] + new_col_names <- names(definition)[!names(definition) == "condition"] condition <- definition[["condition"]] # could also be outside of the function # (re)apply the function for each new variable name and iteratively derive the categories diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index f117a99af..99a42708e 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -3,7 +3,7 @@ Code result Output - # A tibble: 254 x 5 + # A tibble: 10 x 5 USUBJID VSTEST AVAL AVALCAT1 AVALCA1N 1 01-701-1015 Height 147. <160 2 @@ -16,7 +16,6 @@ 8 01-701-1111 Height 158. <160 2 9 01-701-1115 Height 182. >=160 1 10 01-701-1118 Height 180. >=160 1 - # i 244 more rows # derive_vars_cat Test 2: Error when dataset is not a dataframe @@ -35,7 +34,7 @@ Code result Output - # A tibble: 254 x 5 + # A tibble: 10 x 5 USUBJID VSTEST AVAL AVALCAT1 AVALCA1N 1 01-701-1015 Height 147. NA @@ -48,14 +47,13 @@ 8 01-701-1111 Height 158. NA 9 01-701-1115 Height 182. NA 10 01-701-1118 Height 180. NA - # i 244 more rows # derive_vars_cat Test 6: Overlapping conditions handled correctly Code result Output - # A tibble: 254 x 5 + # A tibble: 10 x 5 USUBJID VSTEST AVAL AVALCAT1 AVALCA1N 1 01-701-1015 Height 147. NA @@ -68,14 +66,13 @@ 8 01-701-1111 Height 158. >155 2 9 01-701-1115 Height 182. >=160 1 10 01-701-1118 Height 180. >=160 1 - # i 244 more rows # derive_vars_cat Test 7: Handles missing values in dataset correctly Code result Output - # A tibble: 254 x 5 + # A tibble: 10 x 5 USUBJID VSTEST AVAL AVALCAT1 AVALCA1N 1 01-701-1015 Height NA NA @@ -88,9 +85,8 @@ 8 01-701-1111 Height 158. <160 2 9 01-701-1115 Height 182. >=160 1 10 01-701-1118 Height 180. >=160 1 - # i 244 more rows -# derive_vars_cat Test 8: Error when condition is missing from exprs() definition object +# derive_vars_cat Test 8: Error when condition is missing from `definition` Required variable `condition` is missing in `definition` @@ -99,27 +95,36 @@ Code result Output - # A tibble: 2,493 x 5 - USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - - 1 01-701-1015 Height 147. Height < 160 2 - 2 01-701-1015 Weight 54.0 Weight < 66.68 4 - 3 01-701-1015 Weight 54.4 Weight < 66.68 4 - 4 01-701-1015 Weight 53.1 Weight < 66.68 4 - 5 01-701-1015 Weight 54.0 Weight < 66.68 4 - 6 01-701-1015 Weight 53.1 Weight < 66.68 4 - 7 01-701-1015 Weight 53.1 Weight < 66.68 4 - 8 01-701-1015 Weight 53.1 Weight < 66.68 4 - 9 01-701-1015 Weight 53.1 Weight < 66.68 4 - 10 01-701-1015 Weight 53.1 Weight < 66.68 4 - # i 2,483 more rows + # A tibble: 20 x 5 + USUBJID VSTEST AVAL AVALCAT1 AVALCA1N + + 1 01-701-1015 Height 147. Height < 160 2 + 2 01-701-1015 Weight 54.0 Weight < 66.68 4 + 3 01-701-1023 Height 163. Height >= 160 1 + 4 01-701-1023 Weight 78.5 Weight >= 66.68 3 + 5 01-701-1028 Height 178. Height >= 160 1 + 6 01-701-1028 Weight 98.9 Weight >= 66.68 3 + 7 01-701-1033 Height 175. Height >= 160 1 + 8 01-701-1033 Weight 88.4 Weight >= 66.68 3 + 9 01-701-1034 Height 155. Height < 160 2 + 10 01-701-1034 Weight 63.5 Weight < 66.68 4 + 11 01-701-1047 Height 149. Height < 160 2 + 12 01-701-1047 Weight 66.2 Weight < 66.68 4 + 13 01-701-1097 Height 169. Height >= 160 1 + 14 01-701-1097 Weight 78.0 Weight >= 66.68 3 + 15 01-701-1111 Height 158. Height < 160 2 + 16 01-701-1111 Weight 60.3 Weight < 66.68 4 + 17 01-701-1115 Height 182. Height >= 160 1 + 18 01-701-1115 Weight 78.7 Weight >= 66.68 3 + 19 01-701-1118 Height 180. Height >= 160 1 + 20 01-701-1118 Weight 71.7 Weight >= 66.68 3 # derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset Code result Output - # A tibble: 254 x 6 + # A tibble: 10 x 6 USUBJID VSTEST AVAL AVALCAT1 AVALCA1N extra_var 1 01-701-1015 Height 147. <160 2 FALSE @@ -132,5 +137,4 @@ 8 01-701-1111 Height 158. <160 2 FALSE 9 01-701-1115 Height 182. >=160 1 TRUE 10 01-701-1118 Height 180. >=160 1 TRUE - # i 244 more rows diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index 3876df15a..c20ddacaf 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -1,5 +1,27 @@ # Load the advs dataset -advs <- pharmaverseadam::advs +advs <- tibble::tribble( + ~USUBJID, ~VSTEST, ~AVAL, + "01-701-1015", "Height", 147.32, + "01-701-1015", "Weight", 53.98, + "01-701-1023", "Height", 162.56, + "01-701-1023", "Weight", 78.47, + "01-701-1028", "Height", 177.8, + "01-701-1028", "Weight", 98.88, + "01-701-1033", "Height", 175.26, + "01-701-1033", "Weight", 88.45, + "01-701-1034", "Height", 154.94, + "01-701-1034", "Weight", 63.5, + "01-701-1047", "Height", 148.59, + "01-701-1047", "Weight", 66.23, + "01-701-1097", "Height", 168.91, + "01-701-1097", "Weight", 78.02, + "01-701-1111", "Height", 158.24, + "01-701-1111", "Weight", 60.33, + "01-701-1115", "Height", 181.61, + "01-701-1115", "Weight", 78.7, + "01-701-1118", "Height", 180.34, + "01-701-1118", "Weight", 71.67 +) ## Test 1: Basic functionality with advs dataset ---- test_that("derive_vars_cat Test 1: Basic functionality with advs dataset", { From 7c8d4fb5e742d7bebc7103f1a007a5dbf888e200 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 5 Sep 2024 19:57:51 +0000 Subject: [PATCH 08/83] update manual --- man/derive_vars_cat.Rd | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 5eddbc680..937bc65f2 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -22,15 +22,39 @@ Derive pair of variables } \examples{ -advs <- pharmaverseadam::advs +advs <- tibble::tribble( + ~USUBJID, ~VSTEST, ~AVAL, + "01-701-1015", "Height", 147.32, + "01-701-1015", "Weight", 53.98, + "01-701-1023", "Height", 162.56, + "01-701-1023", "Weight", 78.47, + "01-701-1028", "Height", 177.8, + "01-701-1028", "Weight", 98.88, + "01-701-1033", "Height", 175.26, + "01-701-1033", "Weight", 88.45, + "01-701-1034", "Height", 154.94, + "01-701-1034", "Weight", 63.5, + "01-701-1047", "Height", 148.59, + "01-701-1047", "Weight", 66.23, + "01-701-1097", "Height", 168.91, + "01-701-1097", "Weight", 78.02, + "01-701-1111", "Height", 158.24, + "01-701-1111", "Weight", 60.33, + "01-701-1115", "Height", 181.61, + "01-701-1115", "Weight", 78.7, + "01-701-1118", "Height", 180.34, + "01-701-1118", "Weight", 71.67 +) definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, - VSTESTCD == "Height" & AVAL > 140, ">140 cm", 1, "extra1", - VSTESTCD == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" + ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, + VSTESTCD == "Height" & AVAL > 140, ">140 cm", 1, "extra1", + VSTESTCD == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" ) -derive_vars_cat(dataset = advs \%>\% filter(VSTESTCD == "Height"), - definition = definition) \%>\% +derive_vars_cat( + dataset = advs \%>\% filter(VSTESTCD == "Height"), + definition = definition +) \%>\% select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) } From b2a1a26aa8e7968479b322f0c6f7a22801816bfa Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 5 Sep 2024 20:36:32 +0000 Subject: [PATCH 09/83] fix select --- R/derive_vars_cat.R | 2 +- man/derive_vars_cat.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 9b763bc0a..ed256819b 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -44,7 +44,7 @@ #' dataset = advs %>% filter(VSTESTCD == "Height"), #' definition = definition #' ) %>% -#' select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) +#' dplyr::select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) derive_vars_cat <- function(dataset, definition) { # assertions diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 937bc65f2..f3c3aa84b 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -56,5 +56,5 @@ derive_vars_cat( dataset = advs \%>\% filter(VSTESTCD == "Height"), definition = definition ) \%>\% - select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) + dplyr::select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) } From 269d3b2625da6398c5af54ab4bf1100efe7adeac Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 6 Sep 2024 10:41:35 +0000 Subject: [PATCH 10/83] fix example --- R/derive_vars_cat.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index ed256819b..ccea0de3d 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -36,15 +36,15 @@ #' #' definition <- exprs( #' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, -#' VSTESTCD == "Height" & AVAL > 140, ">140 cm", 1, "extra1", -#' VSTESTCD == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" +#' VSTEST == "Height" & AVAL > 140, ">140 cm", 1, "extra1", +#' VSTEST == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" #' ) #' #' derive_vars_cat( -#' dataset = advs %>% filter(VSTESTCD == "Height"), +#' dataset = advs %>% filter(VSTEST == "Height"), #' definition = definition #' ) %>% -#' dplyr::select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) +#' dplyr::select(USUBJID, VSTEST, AVAL, AVALCA1N, AVALCAT1) derive_vars_cat <- function(dataset, definition) { # assertions From 04335379baafa3a5f68159ffe4f6ca15b6855677 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 6 Sep 2024 10:47:36 +0000 Subject: [PATCH 11/83] update news.md --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 52632e3be..24892c1f7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ ## New Features +- New function `derive_vars_cat()` for deriving pairs of variables or more, e.g. +`MCRITyML` & `MCRITyMN`. (#2480) - New function `derive_vars_crit_flag()` for deriving criterion flag variables (`CRITy`, `CRITyFL`, `CRITyFLN`). (#2468) From ba088b1f3a743db4c7fc205d7e9c5be90ccb6420 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 6 Sep 2024 11:27:02 +0000 Subject: [PATCH 12/83] fix VSTEST --- man/derive_vars_cat.Rd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index f3c3aa84b..54cad58df 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -48,13 +48,13 @@ advs <- tibble::tribble( definition <- exprs( ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, - VSTESTCD == "Height" & AVAL > 140, ">140 cm", 1, "extra1", - VSTESTCD == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" + VSTEST == "Height" & AVAL > 140, ">140 cm", 1, "extra1", + VSTEST == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" ) derive_vars_cat( - dataset = advs \%>\% filter(VSTESTCD == "Height"), + dataset = advs \%>\% filter(VSTEST == "Height"), definition = definition ) \%>\% - dplyr::select(USUBJID, VSTESTCD, AVAL, AVALCA1N, AVALCAT1) + dplyr::select(USUBJID, VSTEST, AVAL, AVALCA1N, AVALCAT1) } From ad514a0c380253a62522a8b1478e2e1ac7dabf16 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 6 Sep 2024 11:40:06 +0000 Subject: [PATCH 13/83] fix example --- R/derive_vars_cat.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index ccea0de3d..378f64561 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -43,8 +43,8 @@ #' derive_vars_cat( #' dataset = advs %>% filter(VSTEST == "Height"), #' definition = definition -#' ) %>% -#' dplyr::select(USUBJID, VSTEST, AVAL, AVALCA1N, AVALCAT1) +#' ) + derive_vars_cat <- function(dataset, definition) { # assertions From 7d4a3e3fd472bd62368cc7244d4b718918563dfd Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 6 Sep 2024 11:49:31 +0000 Subject: [PATCH 14/83] fix documentation --- R/derive_vars_cat.R | 1 - man/derive_vars_cat.Rd | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 378f64561..7ea21682d 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -44,7 +44,6 @@ #' dataset = advs %>% filter(VSTEST == "Height"), #' definition = definition #' ) - derive_vars_cat <- function(dataset, definition) { # assertions diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 54cad58df..1b6207e9b 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -55,6 +55,5 @@ definition <- exprs( derive_vars_cat( dataset = advs \%>\% filter(VSTEST == "Height"), definition = definition -) \%>\% - dplyr::select(USUBJID, VSTEST, AVAL, AVALCA1N, AVALCAT1) +) } From 74f1e813da2fa91b3e7a08c831c6d72aafd785ca Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 6 Sep 2024 11:59:01 +0000 Subject: [PATCH 15/83] update filter --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 7ea21682d..9973d0f5e 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -41,7 +41,7 @@ #' ) #' #' derive_vars_cat( -#' dataset = advs %>% filter(VSTEST == "Height"), +#' dataset = advs %>% dplyr::filter(VSTEST == "Height"), #' definition = definition #' ) derive_vars_cat <- function(dataset, From 234199eedb6dd4b539cb002d1f0486fdece33ed0 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 6 Sep 2024 12:02:46 +0000 Subject: [PATCH 16/83] update manual --- man/derive_vars_cat.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 1b6207e9b..dc9f38e67 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -53,7 +53,7 @@ definition <- exprs( ) derive_vars_cat( - dataset = advs \%>\% filter(VSTEST == "Height"), + dataset = advs \%>\% dplyr::filter(VSTEST == "Height"), definition = definition ) } From ce4b739bd71f52a51e4ed7d06e1a8c4b2fb5f164 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 6 Sep 2024 13:32:00 +0000 Subject: [PATCH 17/83] added keyword and family --- R/derive_vars_cat.R | 2 ++ man/derive_var_extreme_flag.Rd | 1 + man/derive_var_joined_exist_flag.Rd | 1 + man/derive_var_merged_ef_msrc.Rd | 1 + man/derive_var_merged_exist_flag.Rd | 1 + man/derive_var_merged_summary.Rd | 1 + man/derive_var_obs_number.Rd | 1 + man/derive_var_relative_flag.Rd | 1 + man/derive_vars_cat.Rd | 17 +++++++++++++++++ man/derive_vars_computed.Rd | 1 + man/derive_vars_joined.Rd | 1 + man/derive_vars_merged.Rd | 1 + man/derive_vars_merged_lookup.Rd | 1 + man/derive_vars_transposed.Rd | 1 + 14 files changed, 31 insertions(+) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 9973d0f5e..14a6d4b80 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -6,6 +6,8 @@ #' AVAL < 140, "<140 cm", 2) #' #' @return data frame +#' @family der_gen +#' @keywords der_gen #' @export #' #' @examples diff --git a/man/derive_var_extreme_flag.Rd b/man/derive_var_extreme_flag.Rd index 7deac8668..933f5f0af 100644 --- a/man/derive_var_extreme_flag.Rd +++ b/man/derive_var_extreme_flag.Rd @@ -268,6 +268,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, diff --git a/man/derive_var_joined_exist_flag.Rd b/man/derive_var_joined_exist_flag.Rd index 1a3d9da15..9334f60eb 100644 --- a/man/derive_var_joined_exist_flag.Rd +++ b/man/derive_var_joined_exist_flag.Rd @@ -460,6 +460,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, diff --git a/man/derive_var_merged_ef_msrc.Rd b/man/derive_var_merged_ef_msrc.Rd index 538921116..551c7f7c2 100644 --- a/man/derive_var_merged_ef_msrc.Rd +++ b/man/derive_var_merged_ef_msrc.Rd @@ -194,6 +194,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, diff --git a/man/derive_var_merged_exist_flag.Rd b/man/derive_var_merged_exist_flag.Rd index 70a307167..ffe8701d4 100644 --- a/man/derive_var_merged_exist_flag.Rd +++ b/man/derive_var_merged_exist_flag.Rd @@ -152,6 +152,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, diff --git a/man/derive_var_merged_summary.Rd b/man/derive_var_merged_summary.Rd index e5ce37aa4..532fd263c 100644 --- a/man/derive_var_merged_summary.Rd +++ b/man/derive_var_merged_summary.Rd @@ -160,6 +160,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_exist_flag}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, diff --git a/man/derive_var_obs_number.Rd b/man/derive_var_obs_number.Rd index b727cc7f7..8e4f3a544 100644 --- a/man/derive_var_obs_number.Rd +++ b/man/derive_var_obs_number.Rd @@ -103,6 +103,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_exist_flag}()}, \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, diff --git a/man/derive_var_relative_flag.Rd b/man/derive_var_relative_flag.Rd index 4fc22c056..6f2b70988 100644 --- a/man/derive_var_relative_flag.Rd +++ b/man/derive_var_relative_flag.Rd @@ -179,6 +179,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_exist_flag}()}, \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index dc9f38e67..841a9a25d 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -57,3 +57,20 @@ derive_vars_cat( definition = definition ) } +\seealso{ +General Derivation Functions for all ADaMs that returns variable appended to dataset: +\code{\link{derive_var_extreme_flag}()}, +\code{\link{derive_var_joined_exist_flag}()}, +\code{\link{derive_var_merged_ef_msrc}()}, +\code{\link{derive_var_merged_exist_flag}()}, +\code{\link{derive_var_merged_summary}()}, +\code{\link{derive_var_obs_number}()}, +\code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_computed}()}, +\code{\link{derive_vars_joined}()}, +\code{\link{derive_vars_merged}()}, +\code{\link{derive_vars_merged_lookup}()}, +\code{\link{derive_vars_transposed}()} +} +\concept{der_gen} +\keyword{der_gen} diff --git a/man/derive_vars_computed.Rd b/man/derive_vars_computed.Rd index 205f804d7..7f7542bdd 100644 --- a/man/derive_vars_computed.Rd +++ b/man/derive_vars_computed.Rd @@ -173,6 +173,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, \code{\link{derive_vars_merged_lookup}()}, diff --git a/man/derive_vars_joined.Rd b/man/derive_vars_joined.Rd index 273027087..6c7913918 100644 --- a/man/derive_vars_joined.Rd +++ b/man/derive_vars_joined.Rd @@ -504,6 +504,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_merged}()}, \code{\link{derive_vars_merged_lookup}()}, diff --git a/man/derive_vars_merged.Rd b/man/derive_vars_merged.Rd index 7856510b2..700612a4f 100644 --- a/man/derive_vars_merged.Rd +++ b/man/derive_vars_merged.Rd @@ -333,6 +333,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged_lookup}()}, diff --git a/man/derive_vars_merged_lookup.Rd b/man/derive_vars_merged_lookup.Rd index 349465114..6f057576b 100644 --- a/man/derive_vars_merged_lookup.Rd +++ b/man/derive_vars_merged_lookup.Rd @@ -190,6 +190,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, diff --git a/man/derive_vars_transposed.Rd b/man/derive_vars_transposed.Rd index 53ebc55b9..4292ef297 100644 --- a/man/derive_vars_transposed.Rd +++ b/man/derive_vars_transposed.Rd @@ -118,6 +118,7 @@ General Derivation Functions for all ADaMs that returns variable appended to dat \code{\link{derive_var_merged_summary}()}, \code{\link{derive_var_obs_number}()}, \code{\link{derive_var_relative_flag}()}, +\code{\link{derive_vars_cat}()}, \code{\link{derive_vars_computed}()}, \code{\link{derive_vars_joined}()}, \code{\link{derive_vars_merged}()}, From 3d4bdb93a637e7ea96bdf50a4e0b66ca214f68b5 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 10 Sep 2024 11:27:35 +0000 Subject: [PATCH 18/83] update ad_advs.R template --- inst/templates/ad_advs.R | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/inst/templates/ad_advs.R b/inst/templates/ad_advs.R index fd199c238..044af0af5 100644 --- a/inst/templates/ad_advs.R +++ b/inst/templates/ad_advs.R @@ -53,24 +53,19 @@ range_lookup <- tibble::tribble( "PULSE", 60, 100, 40, 110, "TEMP", 36.5, 37.5, 35, 38 ) -# ASSIGN AVALCAT1 -avalcat_lookup <- tibble::tribble( - ~PARAMCD, ~AVALCA1N, ~AVALCAT1, - "HEIGHT", 1, ">100 cm", - "HEIGHT", 2, "<= 100 cm" +# # Assign AVALCAT1 +# avalcat_lookup <- tibble::tribble( +# ~PARAMCD, ~AVALCA1N, ~AVALCAT1, +# "HEIGHT", 1, ">100 cm", +# "HEIGHT", 2, "<= 100 cm" +# ) +# Assign AVALCATx +avalcax_lookup <- exprs( + ~condition, ~AVALCAT1, ~AVALCA1N, + PARAMCD == "HEIGHT" & AVAL > 140, ">140 cm", 1, + PARAMCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 2 ) -# User defined functions ---- - -# Here are some examples of how you can create your own functions that -# operates on vectors, which can be used in `mutate()`. -format_avalcat1n <- function(param, aval) { - case_when( - param == "HEIGHT" & aval > 140 ~ 1, - param == "HEIGHT" & aval <= 140 ~ 2 - ) -} - # Derivations ---- # Get list of ADSL vars required for derivations @@ -276,7 +271,7 @@ advs <- advs %>% TRTA = TRT01A ) -## Get ASEQ and AVALCATx and add PARAM/PARAMN ---- +# Get ASEQ and AVALCATx and add PARAM/PARAMN ---- advs <- advs %>% # Calculate ASEQ derive_var_obs_number( @@ -285,13 +280,15 @@ advs <- advs %>% order = exprs(PARAMCD, ADT, AVISITN, VISITNUM, ATPTN, DTYPE), check_type = "error" ) %>% - # Derive AVALCA1N and AVALCAT1 - mutate(AVALCA1N = format_avalcat1n(param = PARAMCD, aval = AVAL)) %>% - derive_vars_merged(dataset_add = avalcat_lookup, by_vars = exprs(PARAMCD, AVALCA1N)) %>% + # Define condition and categories using derive_vars_cat + derive_vars_cat( + definition = avalcax_lookup + ) %>% # Derive PARAM and PARAMN derive_vars_merged(dataset_add = select(param_lookup, -VSTESTCD), by_vars = exprs(PARAMCD)) + # Add all ADSL variables advs <- advs %>% derive_vars_merged( From 379c8314766872e321154814801fe93e7050929f Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 12 Sep 2024 17:02:41 +0000 Subject: [PATCH 19/83] updated functionality allows for specifyying by_vars --- R/derive_vars_cat.R | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 14a6d4b80..780ef3e47 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -4,6 +4,8 @@ #' e.g. exprs(~condition, ~AVALCAT1, ~AVALCA1N #' AVAL >= 140, ">=140 cm", 1, #' AVAL < 140, "<140 cm", 2) +#' @param by_vars list of expressions with one element. `NULL` by default. +#' Allows for specifying a single category, e.g. `exprs(PARAMCD)`. #' #' @return data frame #' @family der_gen @@ -41,22 +43,48 @@ #' VSTEST == "Height" & AVAL > 140, ">140 cm", 1, "extra1", #' VSTEST == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" #' ) -#' #' derive_vars_cat( #' dataset = advs %>% dplyr::filter(VSTEST == "Height"), #' definition = definition #' ) +#' +#' definition2 <- exprs( +#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL > 140, ">140 cm", 1, +#' "Height", AVAL <= 140, "<=140 cm", 2 +#' ) +#' +#' derive_vars_cat( +#' dataset = advs, +#' definition = definition2, +#' by_vars = exprs(VSTEST) +#' ) + derive_vars_cat <- function(dataset, - definition) { + definition, + by_vars = NULL) { # assertions assert_data_frame(dataset) assert_expr_list(definition) - assert_data_frame(dataset, required_vars = admiraldev::extract_vars(definition) %>% unique()) + if(!is.null(by_vars)){ + assert_expr_list(by_vars) + assert_data_frame(dataset, required_vars = c(admiraldev::extract_vars(definition) %>% unique(), extract_vars(by_vars))) + + } else{ + assert_data_frame(dataset, required_vars = admiraldev::extract_vars(definition) %>% unique()) + } + # transform definition to tibble names(definition) <- NULL definition <- tibble::tribble(!!!definition) - assert_data_frame(definition, required_vars = exprs(condition)) + if(!is.null(by_vars)){ + assert_data_frame(definition, required_vars = c(exprs(condition), by_vars)) + # add condition + definition <- definition %>% mutate( + condition = extend_condition(as.character(condition), as.character(by_vars), is = !!sym(as.character(by_vars))) %>% parse_exprs() + ) + } else assert_data_frame(definition, required_vars = exprs(condition)) # extract new variable names and conditions @@ -78,3 +106,10 @@ derive_vars_cat <- function(dataset, return(new_dataset) } + +## helper + +definition +extend_condition <- function(cond, var, is) { + paste(cond, " & ", var, " == '", is, "'", sep = "") +} From 881f6f1f627a9fedab8b4b61cd8afbe684d1b455 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 13 Sep 2024 10:30:19 +0000 Subject: [PATCH 20/83] show recursive function --- R/derive_vars_cat.R | 78 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 780ef3e47..5f0dc64f2 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -51,7 +51,9 @@ #' definition2 <- exprs( #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, #' "Height", AVAL > 140, ">140 cm", 1, -#' "Height", AVAL <= 140, "<=140 cm", 2 +#' "Height", AVAL <= 140, "<=140 cm", 2, +#' "Weight", AVAL > 70, ">70 kg", 1, +#' "Weight", AVAL <= 70, "<=70 kg", 2 #' ) #' #' derive_vars_cat( @@ -74,7 +76,6 @@ derive_vars_cat <- function(dataset, assert_data_frame(dataset, required_vars = admiraldev::extract_vars(definition) %>% unique()) } - # transform definition to tibble names(definition) <- NULL definition <- tibble::tribble(!!!definition) @@ -91,6 +92,7 @@ derive_vars_cat <- function(dataset, new_col_names <- names(definition)[!names(definition) == "condition"] condition <- definition[["condition"]] # could also be outside of the function + # (re)apply the function for each new variable name and iteratively derive the categories new_dataset <- reduce(new_col_names, function(.data, col_name) { # extract conditions @@ -113,3 +115,75 @@ definition extend_condition <- function(cond, var, is) { paste(cond, " & ", var, " == '", is, "'", sep = "") } + + +derive_vars_cat_rec <- function(dataset, + definition, + by_vars = NULL) { + # assertions + assert_data_frame(dataset) + if(is.null(by_vars)){ + if(!is.data.frame(definition)){ + names(definition) <- NULL + definition <- tibble::tribble(!!!definition) + } + + + assert_data_frame(dataset, required_vars = admiraldev::extract_vars(definition) %>% unique()) + assert_data_frame(definition, required_vars = exprs(condition)) + + new_col_names <- names(definition)[!names(definition) == "condition"] + condition <- definition[["condition"]] # could also be outside of the function + + # (re)apply the function for each new variable name and iteratively derive the categories + new_dataset <- reduce(new_col_names, function(.data, col_name) { + # extract conditions + values <- definition[[col_name]] + # extract values + + .data %>% + mutate(!!sym(col_name) := eval(rlang::call2( + "case_when", + !!!map2(condition, values, ~ expr(!!.x ~ !!.y)) + ))) + }, .init = dataset) + + return(new_dataset) + } + + assert_expr_list(definition) + + names(definition) <- NULL + definition <- tibble::tribble(!!!definition) + der_slice_list <- definition %>% group_by(!!sym(by_vars[[1]])) %>% + dplyr::group_split() %>% lapply(FUN = function(x) { + + var <- x %>% pull(by_vars[[1]]) %>% unique() + def <- x %>% select(-by_vars[[1]]) + + derivation_slice(filter = !!sym(by_vars[[1]]) == !!var, + args = params(definition = !!def)) + } + ) + + + args <- list(dataset = dataset, derivation = derive_vars_cat_rec, args = NULL) + args <- c(args, der_slice_list) + result <- do.call(slice_derivation, args = args) + return(result) +} + +#' +#' definition2 <- exprs( +#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL > 140, ">140 cm", 1, +#' "Height", AVAL <= 140, "<=140 cm", 2, +#' "Weight", AVAL > 70, ">70 kg", 1, +#' "Weight", AVAL <= 70, "<=70 kg", 2 +#' ) + +# derive_vars_cat_rec( +# dataset = advs, +# definition = definition2, +# by_vars = exprs(VSTEST) +# ) From c19e4ee6dff9dd21abd18858183d4a1e7da70c4d Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 20 Sep 2024 13:52:14 +0000 Subject: [PATCH 21/83] fix bug and improve documentation --- R/derive_vars_cat.R | 164 +++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 86 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 5f0dc64f2..80ee1d7de 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -1,11 +1,63 @@ #' Derive pair of variables -#' @param dataset data frame containing the variables specified in the conditions -#' @param definition of condition and values defined as `exprs()` object. -#' e.g. exprs(~condition, ~AVALCAT1, ~AVALCA1N -#' AVAL >= 140, ">=140 cm", 1, -#' AVAL < 140, "<140 cm", 2) +#' @param dataset +#' `r roxygen_param_dataset(expected_vars = c("by_vars", "definition"))` +#' @param definition List of expressions created by: `exprs()`. +#' Must be in the format of a tribble. +#' Must contain: +#' - the column `condition` which evaluates to a logic in `dataset`. +#' - at least one additional column with the new column name and the category value. +#' - the column specified in `by_vars` (if `by_vars` is specified) +#' +#' e.g. if `by_vars` is not specified: +#' `exprs(~condition, ~AVALCAT1, ~AVALCA1N +#' AVAL >= 140, ">=140 cm", 1, +#' AVAL < 140, "<140 cm", 2)` +#' +#' e.g. if `by_vars` is specified as `exprs(VSTEST)`: +#' `exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N +#' "Height", AVAL >= 140, ">=140 cm", 1, +#' "Height", AVAL < 140, "<140 cm", 2)` +#' #' @param by_vars list of expressions with one element. `NULL` by default. -#' Allows for specifying a single category, e.g. `exprs(PARAMCD)`. +#' Allows for specifying by groups, e.g. `exprs(PARAMCD)`. +#' Variable must be present in both `dataset` and `definition`. +#' The conditions in `definition` are applied only to those records that match `by_vars`. +#' The categorization variables are set to NA for records not matching any of the by groups in `definition`. +#' +#' +#' @details +#' If conditions are overlapping, the row order of `definitions` must be carefully considered. +#' The **first** match will determine the category. +#' i.e. if +#' +#' `AVAL = 155` +#' +#' and the `definition` is: +#' +#' definition <- exprs( +#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL > 170, ">170 cm", 1, +#' "Height", AVAL <= 170, "<=170 cm", 2, +#' "Height", AVAL <= 160, "<=160 cm", 3, +#' ) +#' +#' then `AVALCAT1` will be `"<=170 cm"`, as this is the first match for `AVAL`. +#' If you specify: +#' +#' definition <- exprs( +#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL <= 160, "<=160 cm", 3, +#' "Height", AVAL <= 170, "<=170 cm", 2, +#' "Height", AVAL > 170, ">170 cm", 1, +#' ) +#' +#' Then `AVAL <= 160` will lead to `AVALCAT1 == "<=160 cm"`, +#' `AVAL` inbetween `160` and `170` will lead to `AVALCAT1 == "<=170 cm"`, +#' and `AVAL <= 170` will lead to `AVALCAT1 == ">170 cm"`. +#' +#' However, we suggest to be more explicit when defining the `condition`, to avoid overlap. +#' In this case, the middle condition should be: +#' `AVAL <= 170 & AVAL > 160` #' #' @return data frame #' @family der_gen @@ -47,7 +99,7 @@ #' dataset = advs %>% dplyr::filter(VSTEST == "Height"), #' definition = definition #' ) -#' +#' # using by_vars: #' definition2 <- exprs( #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, #' "Height", AVAL > 140, ">140 cm", 1, @@ -61,6 +113,20 @@ #' definition = definition2, #' by_vars = exprs(VSTEST) #' ) +#' +#' # With three conditions: +#' definition3 <- exprs( +#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL > 170, ">170 cm", 1, +#' "Height", AVAL <= 170 & AVAL > 160, "<=170 cm", 2, +#' "Height", AVAL <= 160, "<=160 cm", 3, +#' ) +#' +#' derive_vars_cat( +#' dataset = advs, +#' definition = definition3, +#' by_vars = exprs(VSTEST) +#' ) derive_vars_cat <- function(dataset, definition, @@ -69,9 +135,8 @@ derive_vars_cat <- function(dataset, assert_data_frame(dataset) assert_expr_list(definition) if(!is.null(by_vars)){ - assert_expr_list(by_vars) - assert_data_frame(dataset, required_vars = c(admiraldev::extract_vars(definition) %>% unique(), extract_vars(by_vars))) - + assert_vars(by_vars) + assert_data_frame(dataset, required_vars = c(admiraldev::extract_vars(definition) %>% unique(), by_vars)) } else{ assert_data_frame(dataset, required_vars = admiraldev::extract_vars(definition) %>% unique()) } @@ -79,14 +144,13 @@ derive_vars_cat <- function(dataset, # transform definition to tibble names(definition) <- NULL definition <- tibble::tribble(!!!definition) + assert_data_frame(definition, required_vars = c(exprs(condition), by_vars)) if(!is.null(by_vars)){ - assert_data_frame(definition, required_vars = c(exprs(condition), by_vars)) # add condition definition <- definition %>% mutate( condition = extend_condition(as.character(condition), as.character(by_vars), is = !!sym(as.character(by_vars))) %>% parse_exprs() - ) - } else assert_data_frame(definition, required_vars = exprs(condition)) - + ) %>% select(-by_vars[[1]]) + } # extract new variable names and conditions new_col_names <- names(definition)[!names(definition) == "condition"] @@ -115,75 +179,3 @@ definition extend_condition <- function(cond, var, is) { paste(cond, " & ", var, " == '", is, "'", sep = "") } - - -derive_vars_cat_rec <- function(dataset, - definition, - by_vars = NULL) { - # assertions - assert_data_frame(dataset) - if(is.null(by_vars)){ - if(!is.data.frame(definition)){ - names(definition) <- NULL - definition <- tibble::tribble(!!!definition) - } - - - assert_data_frame(dataset, required_vars = admiraldev::extract_vars(definition) %>% unique()) - assert_data_frame(definition, required_vars = exprs(condition)) - - new_col_names <- names(definition)[!names(definition) == "condition"] - condition <- definition[["condition"]] # could also be outside of the function - - # (re)apply the function for each new variable name and iteratively derive the categories - new_dataset <- reduce(new_col_names, function(.data, col_name) { - # extract conditions - values <- definition[[col_name]] - # extract values - - .data %>% - mutate(!!sym(col_name) := eval(rlang::call2( - "case_when", - !!!map2(condition, values, ~ expr(!!.x ~ !!.y)) - ))) - }, .init = dataset) - - return(new_dataset) - } - - assert_expr_list(definition) - - names(definition) <- NULL - definition <- tibble::tribble(!!!definition) - der_slice_list <- definition %>% group_by(!!sym(by_vars[[1]])) %>% - dplyr::group_split() %>% lapply(FUN = function(x) { - - var <- x %>% pull(by_vars[[1]]) %>% unique() - def <- x %>% select(-by_vars[[1]]) - - derivation_slice(filter = !!sym(by_vars[[1]]) == !!var, - args = params(definition = !!def)) - } - ) - - - args <- list(dataset = dataset, derivation = derive_vars_cat_rec, args = NULL) - args <- c(args, der_slice_list) - result <- do.call(slice_derivation, args = args) - return(result) -} - -#' -#' definition2 <- exprs( -#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, -#' "Height", AVAL > 140, ">140 cm", 1, -#' "Height", AVAL <= 140, "<=140 cm", 2, -#' "Weight", AVAL > 70, ">70 kg", 1, -#' "Weight", AVAL <= 70, "<=70 kg", 2 -#' ) - -# derive_vars_cat_rec( -# dataset = advs, -# definition = definition2, -# by_vars = exprs(VSTEST) -# ) From 265ecea85ac6a0734f861dc8981b002b6c727c1b Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 20 Sep 2024 15:08:25 +0000 Subject: [PATCH 22/83] updated tests --- R/derive_vars_cat.R | 23 ++- tests/testthat/_snaps/derive_vars_cat.md | 239 +++++++++++++---------- tests/testthat/test-derive_vars_cat.R | 147 ++++++++------ 3 files changed, 236 insertions(+), 173 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 80ee1d7de..87548d5b2 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -38,7 +38,7 @@ #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, #' "Height", AVAL > 170, ">170 cm", 1, #' "Height", AVAL <= 170, "<=170 cm", 2, -#' "Height", AVAL <= 160, "<=160 cm", 3, +#' "Height", AVAL <= 160, "<=160 cm", 3 #' ) #' #' then `AVALCAT1` will be `"<=170 cm"`, as this is the first match for `AVAL`. @@ -48,7 +48,7 @@ #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, #' "Height", AVAL <= 160, "<=160 cm", 3, #' "Height", AVAL <= 170, "<=170 cm", 2, -#' "Height", AVAL > 170, ">170 cm", 1, +#' "Height", AVAL > 170, ">170 cm", 1 #' ) #' #' Then `AVAL <= 160` will lead to `AVALCAT1 == "<=160 cm"`, @@ -92,8 +92,8 @@ #' #' definition <- exprs( #' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, -#' VSTEST == "Height" & AVAL > 140, ">140 cm", 1, "extra1", -#' VSTEST == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" +#' VSTEST == "Height" & AVAL > 160, ">160 cm", 1, "extra1", +#' VSTEST == "Height" & AVAL <= 160, "<=160 cm", 2, "extra2" #' ) #' derive_vars_cat( #' dataset = advs %>% dplyr::filter(VSTEST == "Height"), @@ -102,8 +102,8 @@ #' # using by_vars: #' definition2 <- exprs( #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, -#' "Height", AVAL > 140, ">140 cm", 1, -#' "Height", AVAL <= 140, "<=140 cm", 2, +#' "Height", AVAL > 160, ">160 cm", 1, +#' "Height", AVAL <= 160, "<=160 cm", 2, #' "Weight", AVAL > 70, ">70 kg", 1, #' "Weight", AVAL <= 70, "<=70 kg", 2 #' ) @@ -119,7 +119,7 @@ #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, #' "Height", AVAL > 170, ">170 cm", 1, #' "Height", AVAL <= 170 & AVAL > 160, "<=170 cm", 2, -#' "Height", AVAL <= 160, "<=160 cm", 3, +#' "Height", AVAL <= 160, "<=160 cm", 3 #' ) #' #' derive_vars_cat( @@ -143,7 +143,12 @@ derive_vars_cat <- function(dataset, # transform definition to tibble names(definition) <- NULL - definition <- tibble::tribble(!!!definition) + definition <- tryCatch( + {tibble::tribble(!!!definition)}, + error = function(e) { + # Catch the error and append your own message + stop("Failed to convert `definition` to tribble: ", e$message) + }) assert_data_frame(definition, required_vars = c(exprs(condition), by_vars)) if(!is.null(by_vars)){ # add condition @@ -174,8 +179,6 @@ derive_vars_cat <- function(dataset, } ## helper - -definition extend_condition <- function(cond, var, is) { paste(cond, " & ", var, " == '", is, "'", sep = "") } diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index 99a42708e..14262c2e0 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -3,94 +3,123 @@ Code result Output - # A tibble: 10 x 5 + # A tibble: 20 x 5 USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - 1 01-701-1015 Height 147. <160 2 - 2 01-701-1023 Height 163. >=160 1 - 3 01-701-1028 Height 178. >=160 1 - 4 01-701-1033 Height 175. >=160 1 - 5 01-701-1034 Height 155. <160 2 - 6 01-701-1047 Height 149. <160 2 - 7 01-701-1097 Height 169. >=160 1 - 8 01-701-1111 Height 158. <160 2 - 9 01-701-1115 Height 182. >=160 1 - 10 01-701-1118 Height 180. >=160 1 - -# derive_vars_cat Test 2: Error when dataset is not a dataframe + 1 01-701-1015 Height 147. <160 2 + 2 01-701-1023 Height 163. >=160 1 + 3 01-701-1028 Height 178. >=160 1 + 4 01-701-1033 Height 175. >=160 1 + 5 01-701-1034 Height NA NA + 6 01-701-1047 Height NA NA + 7 01-701-1097 Height 169. >=160 1 + 8 01-701-1111 Height 158. <160 2 + 9 01-701-1115 Height 182. >=160 1 + 10 01-701-1118 Height 180. >=160 1 + 11 01-701-1015 Weight 54.0 NA + 12 01-701-1023 Weight 78.5 NA + 13 01-701-1028 Weight 98.9 NA + 14 01-701-1033 Weight 88.4 NA + 15 01-701-1034 Weight NA NA + 16 01-701-1047 Weight NA NA + 17 01-701-1097 Weight 78.0 NA + 18 01-701-1111 Weight 60.3 NA + 19 01-701-1115 Weight 78.7 NA + 20 01-701-1118 Weight 71.7 NA + +--- - Argument `dataset` must be class , but is a list. + Code + result2 + Output + # A tibble: 20 x 5 + USUBJID VSTEST AVAL AVALCAT1 AVALCA1N + + 1 01-701-1015 Height 147. <160 2 + 2 01-701-1023 Height 163. >=160 1 + 3 01-701-1028 Height 178. >=160 1 + 4 01-701-1033 Height 175. >=160 1 + 5 01-701-1034 Height NA NA + 6 01-701-1047 Height NA NA + 7 01-701-1097 Height 169. >=160 1 + 8 01-701-1111 Height 158. <160 2 + 9 01-701-1115 Height 182. >=160 1 + 10 01-701-1118 Height 180. >=160 1 + 11 01-701-1015 Weight 54.0 NA + 12 01-701-1023 Weight 78.5 NA + 13 01-701-1028 Weight 98.9 NA + 14 01-701-1033 Weight 88.4 NA + 15 01-701-1034 Weight NA NA + 16 01-701-1047 Weight NA NA + 17 01-701-1097 Weight 78.0 NA + 18 01-701-1111 Weight 60.3 NA + 19 01-701-1115 Weight 78.7 NA + 20 01-701-1118 Weight 71.7 NA # derive_vars_cat Test 3: Error when definition is not an exprs object - Must specify at least one column using the `~name` syntax. - -# derive_vars_cat Test 4: Error when required columns are missing from dataset - - Required variable `VSTEST` is missing in `dataset` + Argument `definition` must be a list of expressions but is a tibble. + i To create a list of expressions use `exprs()`. # derive_vars_cat Test 5: Correct behavior when no conditions are met Code result Output - # A tibble: 10 x 5 + # A tibble: 20 x 5 USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - 1 01-701-1015 Height 147. NA - 2 01-701-1023 Height 163. NA - 3 01-701-1028 Height 178. NA - 4 01-701-1033 Height 175. NA - 5 01-701-1034 Height 155. NA - 6 01-701-1047 Height 149. NA - 7 01-701-1097 Height 169. NA - 8 01-701-1111 Height 158. NA - 9 01-701-1115 Height 182. NA - 10 01-701-1118 Height 180. NA + 1 01-701-1015 Height 147. NA + 2 01-701-1023 Height 163. NA + 3 01-701-1028 Height 178. NA + 4 01-701-1033 Height 175. NA + 5 01-701-1034 Height NA NA + 6 01-701-1047 Height NA NA + 7 01-701-1097 Height 169. NA + 8 01-701-1111 Height 158. NA + 9 01-701-1115 Height 182. NA + 10 01-701-1118 Height 180. NA + 11 01-701-1015 Weight 54.0 NA + 12 01-701-1023 Weight 78.5 NA + 13 01-701-1028 Weight 98.9 NA + 14 01-701-1033 Weight 88.4 NA + 15 01-701-1034 Weight NA NA + 16 01-701-1047 Weight NA NA + 17 01-701-1097 Weight 78.0 NA + 18 01-701-1111 Weight 60.3 NA + 19 01-701-1115 Weight 78.7 NA + 20 01-701-1118 Weight 71.7 NA # derive_vars_cat Test 6: Overlapping conditions handled correctly Code result Output - # A tibble: 10 x 5 - USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - - 1 01-701-1015 Height 147. NA - 2 01-701-1023 Height 163. >=160 1 - 3 01-701-1028 Height 178. >=160 1 - 4 01-701-1033 Height 175. >=160 1 - 5 01-701-1034 Height 155. NA - 6 01-701-1047 Height 149. NA - 7 01-701-1097 Height 169. >=160 1 - 8 01-701-1111 Height 158. >155 2 - 9 01-701-1115 Height 182. >=160 1 - 10 01-701-1118 Height 180. >=160 1 - -# derive_vars_cat Test 7: Handles missing values in dataset correctly - - Code - result - Output - # A tibble: 10 x 5 + # A tibble: 20 x 5 USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - 1 01-701-1015 Height NA NA - 2 01-701-1023 Height NA NA - 3 01-701-1028 Height NA NA - 4 01-701-1033 Height NA NA - 5 01-701-1034 Height NA NA - 6 01-701-1047 Height 149. <160 2 - 7 01-701-1097 Height 169. >=160 1 - 8 01-701-1111 Height 158. <160 2 - 9 01-701-1115 Height 182. >=160 1 - 10 01-701-1118 Height 180. >=160 1 - -# derive_vars_cat Test 8: Error when condition is missing from `definition` - - Required variable `condition` is missing in `definition` - -# derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and BILI) + 1 01-701-1015 Height 147. <160 3 + 2 01-701-1023 Height 163. <170 2 + 3 01-701-1028 Height 178. >=170 1 + 4 01-701-1033 Height 175. >=170 1 + 5 01-701-1034 Height NA NA + 6 01-701-1047 Height NA NA + 7 01-701-1097 Height 169. <170 2 + 8 01-701-1111 Height 158. <160 3 + 9 01-701-1115 Height 182. >=170 1 + 10 01-701-1118 Height 180. >=170 1 + 11 01-701-1015 Weight 54.0 NA + 12 01-701-1023 Weight 78.5 NA + 13 01-701-1028 Weight 98.9 NA + 14 01-701-1033 Weight 88.4 NA + 15 01-701-1034 Weight NA NA + 16 01-701-1047 Weight NA NA + 17 01-701-1097 Weight 78.0 NA + 18 01-701-1111 Weight 60.3 NA + 19 01-701-1115 Weight 78.7 NA + 20 01-701-1118 Weight 71.7 NA + +# derive_vars_cat Test 8: Conditions for multiple VSTESTs (Height and Weight) Code result @@ -99,42 +128,56 @@ USUBJID VSTEST AVAL AVALCAT1 AVALCA1N 1 01-701-1015 Height 147. Height < 160 2 - 2 01-701-1015 Weight 54.0 Weight < 66.68 4 - 3 01-701-1023 Height 163. Height >= 160 1 - 4 01-701-1023 Weight 78.5 Weight >= 66.68 3 - 5 01-701-1028 Height 178. Height >= 160 1 - 6 01-701-1028 Weight 98.9 Weight >= 66.68 3 - 7 01-701-1033 Height 175. Height >= 160 1 - 8 01-701-1033 Weight 88.4 Weight >= 66.68 3 - 9 01-701-1034 Height 155. Height < 160 2 - 10 01-701-1034 Weight 63.5 Weight < 66.68 4 - 11 01-701-1047 Height 149. Height < 160 2 - 12 01-701-1047 Weight 66.2 Weight < 66.68 4 - 13 01-701-1097 Height 169. Height >= 160 1 - 14 01-701-1097 Weight 78.0 Weight >= 66.68 3 - 15 01-701-1111 Height 158. Height < 160 2 - 16 01-701-1111 Weight 60.3 Weight < 66.68 4 - 17 01-701-1115 Height 182. Height >= 160 1 - 18 01-701-1115 Weight 78.7 Weight >= 66.68 3 - 19 01-701-1118 Height 180. Height >= 160 1 - 20 01-701-1118 Weight 71.7 Weight >= 66.68 3 - -# derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset + 2 01-701-1023 Height 163. Height >= 160 1 + 3 01-701-1028 Height 178. Height >= 160 1 + 4 01-701-1033 Height 175. Height >= 160 1 + 5 01-701-1034 Height NA NA + 6 01-701-1047 Height NA NA + 7 01-701-1097 Height 169. Height >= 160 1 + 8 01-701-1111 Height 158. Height < 160 2 + 9 01-701-1115 Height 182. Height >= 160 1 + 10 01-701-1118 Height 180. Height >= 160 1 + 11 01-701-1015 Weight 54.0 Weight < 66.68 2 + 12 01-701-1023 Weight 78.5 Weight >= 66.68 1 + 13 01-701-1028 Weight 98.9 Weight >= 66.68 1 + 14 01-701-1033 Weight 88.4 Weight >= 66.68 1 + 15 01-701-1034 Weight NA NA + 16 01-701-1047 Weight NA NA + 17 01-701-1097 Weight 78.0 Weight >= 66.68 1 + 18 01-701-1111 Weight 60.3 Weight < 66.68 2 + 19 01-701-1115 Weight 78.7 Weight >= 66.68 1 + 20 01-701-1118 Weight 71.7 Weight >= 66.68 1 + +# derive_vars_cat Test 9: Adding an extra variable (flag) to the dataset Code result Output - # A tibble: 10 x 6 + # A tibble: 20 x 6 USUBJID VSTEST AVAL AVALCAT1 AVALCA1N extra_var - 1 01-701-1015 Height 147. <160 2 FALSE - 2 01-701-1023 Height 163. >=160 1 TRUE - 3 01-701-1028 Height 178. >=160 1 TRUE - 4 01-701-1033 Height 175. >=160 1 TRUE - 5 01-701-1034 Height 155. <160 2 FALSE - 6 01-701-1047 Height 149. <160 2 FALSE - 7 01-701-1097 Height 169. >=160 1 TRUE - 8 01-701-1111 Height 158. <160 2 FALSE - 9 01-701-1115 Height 182. >=160 1 TRUE - 10 01-701-1118 Height 180. >=160 1 TRUE + 1 01-701-1015 Height 147. <160 2 FALSE + 2 01-701-1023 Height 163. >=160 1 TRUE + 3 01-701-1028 Height 178. >=160 1 TRUE + 4 01-701-1033 Height 175. >=160 1 TRUE + 5 01-701-1034 Height NA NA NA + 6 01-701-1047 Height NA NA NA + 7 01-701-1097 Height 169. >=160 1 TRUE + 8 01-701-1111 Height 158. <160 2 FALSE + 9 01-701-1115 Height 182. >=160 1 TRUE + 10 01-701-1118 Height 180. >=160 1 TRUE + 11 01-701-1015 Weight 54.0 NA NA + 12 01-701-1023 Weight 78.5 NA NA + 13 01-701-1028 Weight 98.9 NA NA + 14 01-701-1033 Weight 88.4 NA NA + 15 01-701-1034 Weight NA NA NA + 16 01-701-1047 Weight NA NA NA + 17 01-701-1097 Weight 78.0 NA NA + 18 01-701-1111 Weight 60.3 NA NA + 19 01-701-1115 Weight 78.7 NA NA + 20 01-701-1118 Weight 71.7 NA NA + +# derive_vars_cat Test 11: definition has wrong shape + + Failed to convert `definition` to tribble: Data must be rectangular. diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index c20ddacaf..b8c02f543 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -9,10 +9,10 @@ advs <- tibble::tribble( "01-701-1028", "Weight", 98.88, "01-701-1033", "Height", 175.26, "01-701-1033", "Weight", 88.45, - "01-701-1034", "Height", 154.94, - "01-701-1034", "Weight", 63.5, - "01-701-1047", "Height", 148.59, - "01-701-1047", "Weight", 66.23, + "01-701-1034", "Height", NA, + "01-701-1034", "Weight", NA, + "01-701-1047", "Height", NA, + "01-701-1047", "Weight", NA, "01-701-1097", "Height", 168.91, "01-701-1097", "Weight", 78.02, "01-701-1111", "Height", 158.24, @@ -21,7 +21,7 @@ advs <- tibble::tribble( "01-701-1115", "Weight", 78.7, "01-701-1118", "Height", 180.34, "01-701-1118", "Weight", 71.67 -) +) %>% arrange(VSTEST) ## Test 1: Basic functionality with advs dataset ---- test_that("derive_vars_cat Test 1: Basic functionality with advs dataset", { @@ -32,11 +32,20 @@ test_that("derive_vars_cat Test 1: Basic functionality with advs dataset", { VSTEST == "Height" & AVAL < 160, "<160", 2 ) - result <- derive_vars_cat(advs, definition) %>% - select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) %>% - filter(VSTEST == "Height") + result <- derive_vars_cat(advs, definition) + + # using by_vars + definition2 <- exprs( + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160", 2 + ) + + result2 <- derive_vars_cat(advs, definition2, by_vars = exprs(VSTEST)) expect_snapshot(result) + expect_snapshot(result2) + expect_dfs_equal(base = result, compare = result2, keys = c("USUBJID", "VSTEST")) }) ## Test 2: Error when dataset is not a dataframe ---- @@ -49,16 +58,22 @@ test_that("derive_vars_cat Test 2: Error when dataset is not a dataframe", { ) # Snapshot the error message - expect_snapshot_error( - derive_vars_cat(list(1, 2, 3), definition) + expect_error( + derive_vars_cat(list(1, 2, 3), definition), + class = "assert_data_frame" ) }) ## Test 3: Error when definition is not an exprs object ---- test_that("derive_vars_cat Test 3: Error when definition is not an exprs object", { + definition <- tribble( + ~condition, ~AVALCAT1, ~AVALCA1N, + "AVAL >= 160", ">=160", 1, + "AVAL < 160", "<160", 2 + ) # Snapshot the error message expect_snapshot_error( - derive_vars_cat(advs, list(condition = "Height", AVALCAT1 = 1)) + derive_vars_cat(advs, definition) ) }) @@ -66,17 +81,18 @@ test_that("derive_vars_cat Test 3: Error when definition is not an exprs object" test_that("derive_vars_cat Test 4: Error when required columns are missing from dataset", { # Define the condition and categories (without VSTEST in the dataset) definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, - VSTEST == "Height" & AVAL >= 160, ">=160", 1, - VSTEST == "Height" & AVAL < 160, "<160", 2 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160", 2 ) # Remove VSTEST column from dataset advs_missing_col <- advs %>% select(-VSTEST) # Snapshot the error message - expect_snapshot_error( - derive_vars_cat(advs_missing_col, definition) + expect_error( + derive_vars_cat(advs_missing_col, definition, by_vars = exprs(VSTEST)), + class = "assert_data_frame" ) }) @@ -88,9 +104,7 @@ test_that("derive_vars_cat Test 5: Correct behavior when no conditions are met", VSTEST == "Height" & AVAL < 0, "<0", 1 ) - result <- derive_vars_cat(advs, definition) %>% - filter(VSTEST == "Height") %>% - select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) + result <- derive_vars_cat(advs, definition) expect_snapshot(result) }) @@ -99,39 +113,20 @@ test_that("derive_vars_cat Test 5: Correct behavior when no conditions are met", test_that("derive_vars_cat Test 6: Overlapping conditions handled correctly", { # Define overlapping conditions definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, - VSTEST == "Height" & AVAL >= 160, ">=160", 1, - VSTEST == "Height" & AVAL > 155, ">155", 2 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL < 160, "<160", 3, + "Height", AVAL < 170, "<170", 2, + "Height", AVAL >= 170, ">=170", 1 ) - result <- derive_vars_cat(advs, definition) %>% - select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) %>% - filter(VSTEST == "Height") + result <- derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)) expect_snapshot(result) }) -## Test 7: Handles missing values in dataset correctly ---- -test_that("derive_vars_cat Test 7: Handles missing values in dataset correctly", { - # Introduce missing values in AVAL - advs_missing <- advs %>% filter(VSTEST == "Height") - advs_missing$AVAL[1:5] <- NA - - # Define the condition and categories - definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, - VSTEST == "Height" & AVAL >= 160, ">=160", 1, - VSTEST == "Height" & AVAL < 160, "<160", 2 - ) - - result <- derive_vars_cat(advs_missing, definition) %>% - select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) - expect_snapshot(result) -}) - -## Test 8: Error when condition is missing from exprs() definition object ---- -test_that("derive_vars_cat Test 8: Error when condition is missing from `definition`", { +## Test 7: Error when condition is missing from `definition` ---- +test_that("derive_vars_cat Test 7: Error when condition is missing from `definition`", { # Define the condition but omit the 'condition' column from the definition definition <- exprs( ~AVALCAT1, ~AVALCA1N, @@ -140,41 +135,63 @@ test_that("derive_vars_cat Test 8: Error when condition is missing from `definit ) # Snapshot the error message - expect_snapshot_error( - derive_vars_cat(advs, definition) + expect_error( + derive_vars_cat(advs, definition), + class = "assert_data_frame" ) }) -## Test 9: Conditions for multiple VSTESTs (Height and BILI) ---- -test_that("derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and BILI)", { +## Test 8: Conditions for multiple VSTESTs (Height and Weight) ---- +test_that("derive_vars_cat Test 8: Conditions for multiple VSTESTs (Height and Weight)", { # Define conditions for two different VSTEST values: Height and BILI definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, - VSTEST == "Height" & AVAL >= 160, "Height >= 160", 1, - VSTEST == "Height" & AVAL < 160, "Height < 160", 2, - VSTEST == "Weight" & AVAL >= 66.68, "Weight >= 66.68", 3, - VSTEST == "Weight" & AVAL < 66.68, "Weight < 66.68", 4 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, "Height >= 160", 1, + "Height", AVAL < 160, "Height < 160", 2, + "Weight", AVAL >= 66.68, "Weight >= 66.68", 1, + "Weight", AVAL < 66.68, "Weight < 66.68", 2 ) - result <- derive_vars_cat(advs, definition) %>% - select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N) %>% - filter(VSTEST %in% c("Height", "Weight")) + result <- derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)) expect_snapshot(result) }) -## Test 10: Adding an extra variable (flag) to the dataset ---- -test_that("derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset", { +## Test 9: Adding an extra variable (flag) to the dataset ---- +test_that("derive_vars_cat Test 9: Adding an extra variable (flag) to the dataset", { # Define conditions and add a third variable (flag) that is TRUE or FALSE definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, ~extra_var, - VSTEST == "Height" & AVAL >= 160, ">=160", 1, TRUE, - VSTEST == "Height" & AVAL < 160, "<160", 2, FALSE + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, ~extra_var, + "Height", AVAL >= 160, ">=160", 1, TRUE, + "Height", AVAL < 160, "<160", 2, FALSE ) - result <- derive_vars_cat(advs, definition) %>% - select(USUBJID, VSTEST, AVAL, AVALCAT1, AVALCA1N, extra_var) %>% - filter(VSTEST == "Height") + result <- derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)) expect_snapshot(result) }) + +## Test 10: Wrong input for by_vars ---- +test_that("derive_vars_cat Test 10: Wrong input for by_vars", { + # Define conditions + definition <- exprs( + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160", 2 + ) + + expect_error(derive_vars_cat(advs, definition, by_vars = exprs(VSTEST == "Height")), + class = "assert_vars") +}) + +## Test 11: definition has wrong shape ---- +test_that("derive_vars_cat Test 11: definition has wrong shape", { + # Define conditions + definition_wrong_shape <- exprs( + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160" + ) + + expect_snapshot_error(derive_vars_cat(advs, definition_wrong_shape, by_vars = exprs(VSTEST))) +}) From b5041bef4cfb314f0d9e2897963ead20ea1b3ee7 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 20 Sep 2024 15:17:32 +0000 Subject: [PATCH 23/83] add warning for forgotten by_vars --- R/derive_vars_cat.R | 7 +++- tests/testthat/_snaps/derive_vars_cat.md | 17 +++++--- tests/testthat/test-derive_vars_cat.R | 51 ++++++++++++++---------- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 87548d5b2..182e16d2a 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -159,8 +159,13 @@ derive_vars_cat <- function(dataset, # extract new variable names and conditions new_col_names <- names(definition)[!names(definition) == "condition"] - condition <- definition[["condition"]] # could also be outside of the function + condition <- definition[["condition"]] + # warn if new variables already exist + if(any(new_col_names %in% names(dataset))){ + warning(paste("Column(s) in `definition` already exist in `dataset`.", + "Did you forget to specify `by_vars`?", sep = "\n")) + } # (re)apply the function for each new variable name and iteratively derive the categories new_dataset <- reduce(new_col_names, function(.data, col_name) { diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index 14262c2e0..c23963371 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -56,12 +56,17 @@ 19 01-701-1115 Weight 78.7 NA 20 01-701-1118 Weight 71.7 NA -# derive_vars_cat Test 3: Error when definition is not an exprs object +# derive_vars_cat Test 2: Forgot to specify by_vars + + Column(s) in `definition` already exist in `dataset`. + Did you forget to specify `by_vars`? + +# derive_vars_cat Test 4: Error when definition is not an exprs object Argument `definition` must be a list of expressions but is a tibble. i To create a list of expressions use `exprs()`. -# derive_vars_cat Test 5: Correct behavior when no conditions are met +# derive_vars_cat Test 6: Correct behavior when no conditions are met Code result @@ -90,7 +95,7 @@ 19 01-701-1115 Weight 78.7 NA 20 01-701-1118 Weight 71.7 NA -# derive_vars_cat Test 6: Overlapping conditions handled correctly +# derive_vars_cat Test 7: Overlapping conditions handled correctly Code result @@ -119,7 +124,7 @@ 19 01-701-1115 Weight 78.7 NA 20 01-701-1118 Weight 71.7 NA -# derive_vars_cat Test 8: Conditions for multiple VSTESTs (Height and Weight) +# derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and Weight) Code result @@ -148,7 +153,7 @@ 19 01-701-1115 Weight 78.7 Weight >= 66.68 1 20 01-701-1118 Weight 71.7 Weight >= 66.68 1 -# derive_vars_cat Test 9: Adding an extra variable (flag) to the dataset +# derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset Code result @@ -177,7 +182,7 @@ 19 01-701-1115 Weight 78.7 NA NA 20 01-701-1118 Weight 71.7 NA NA -# derive_vars_cat Test 11: definition has wrong shape +# derive_vars_cat Test 12: definition has wrong shape Failed to convert `definition` to tribble: Data must be rectangular. diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index b8c02f543..3a75a1bb4 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -48,8 +48,19 @@ test_that("derive_vars_cat Test 1: Basic functionality with advs dataset", { expect_dfs_equal(base = result, compare = result2, keys = c("USUBJID", "VSTEST")) }) -## Test 2: Error when dataset is not a dataframe ---- -test_that("derive_vars_cat Test 2: Error when dataset is not a dataframe", { +## Test 2: Forgot to specify by_vars ---- +test_that("derive_vars_cat Test 2: Forgot to specify by_vars", { + definition <- exprs( + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160", 2 + ) + + expect_snapshot_warning(derive_vars_cat(advs, definition)) +}) + +## Test 3: Error when dataset is not a dataframe ---- +test_that("derive_vars_cat Test 3: Error when dataset is not a dataframe", { # Define the condition and categories definition <- exprs( ~condition, ~AVALCAT1, ~AVALCA1N, @@ -64,8 +75,8 @@ test_that("derive_vars_cat Test 2: Error when dataset is not a dataframe", { ) }) -## Test 3: Error when definition is not an exprs object ---- -test_that("derive_vars_cat Test 3: Error when definition is not an exprs object", { +## Test 4: Error when definition is not an exprs object ---- +test_that("derive_vars_cat Test 4: Error when definition is not an exprs object", { definition <- tribble( ~condition, ~AVALCAT1, ~AVALCA1N, "AVAL >= 160", ">=160", 1, @@ -77,8 +88,8 @@ test_that("derive_vars_cat Test 3: Error when definition is not an exprs object" ) }) -## Test 4: Error when required columns are missing from dataset ---- -test_that("derive_vars_cat Test 4: Error when required columns are missing from dataset", { +## Test 5: Error when required columns are missing from dataset ---- +test_that("derive_vars_cat Test 5: Error when required columns are missing from dataset", { # Define the condition and categories (without VSTEST in the dataset) definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, @@ -96,8 +107,8 @@ test_that("derive_vars_cat Test 4: Error when required columns are missing from ) }) -## Test 5: Correct behavior when no conditions are met ---- -test_that("derive_vars_cat Test 5: Correct behavior when no conditions are met", { +## Test 6: Correct behavior when no conditions are met ---- +test_that("derive_vars_cat Test 6: Correct behavior when no conditions are met", { # Define conditions that do not match any rows definition <- exprs( ~condition, ~AVALCAT1, ~AVALCA1N, @@ -109,8 +120,8 @@ test_that("derive_vars_cat Test 5: Correct behavior when no conditions are met", expect_snapshot(result) }) -## Test 6: Overlapping conditions handled correctly ---- -test_that("derive_vars_cat Test 6: Overlapping conditions handled correctly", { +## Test 7: Overlapping conditions handled correctly ---- +test_that("derive_vars_cat Test 7: Overlapping conditions handled correctly", { # Define overlapping conditions definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, @@ -125,8 +136,8 @@ test_that("derive_vars_cat Test 6: Overlapping conditions handled correctly", { }) -## Test 7: Error when condition is missing from `definition` ---- -test_that("derive_vars_cat Test 7: Error when condition is missing from `definition`", { +## Test 8: Error when condition is missing from `definition` ---- +test_that("derive_vars_cat Test 8: Error when condition is missing from `definition`", { # Define the condition but omit the 'condition' column from the definition definition <- exprs( ~AVALCAT1, ~AVALCA1N, @@ -141,8 +152,8 @@ test_that("derive_vars_cat Test 7: Error when condition is missing from `definit ) }) -## Test 8: Conditions for multiple VSTESTs (Height and Weight) ---- -test_that("derive_vars_cat Test 8: Conditions for multiple VSTESTs (Height and Weight)", { +## Test 9: Conditions for multiple VSTESTs (Height and Weight) ---- +test_that("derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and Weight)", { # Define conditions for two different VSTEST values: Height and BILI definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, @@ -157,8 +168,8 @@ test_that("derive_vars_cat Test 8: Conditions for multiple VSTESTs (Height and W expect_snapshot(result) }) -## Test 9: Adding an extra variable (flag) to the dataset ---- -test_that("derive_vars_cat Test 9: Adding an extra variable (flag) to the dataset", { +## Test 10: Adding an extra variable (flag) to the dataset ---- +test_that("derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset", { # Define conditions and add a third variable (flag) that is TRUE or FALSE definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, ~extra_var, @@ -171,8 +182,8 @@ test_that("derive_vars_cat Test 9: Adding an extra variable (flag) to the datase expect_snapshot(result) }) -## Test 10: Wrong input for by_vars ---- -test_that("derive_vars_cat Test 10: Wrong input for by_vars", { +## Test 11: Wrong input for by_vars ---- +test_that("derive_vars_cat Test 11: Wrong input for by_vars", { # Define conditions definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, @@ -184,8 +195,8 @@ test_that("derive_vars_cat Test 10: Wrong input for by_vars", { class = "assert_vars") }) -## Test 11: definition has wrong shape ---- -test_that("derive_vars_cat Test 11: definition has wrong shape", { +## Test 12: definition has wrong shape ---- +test_that("derive_vars_cat Test 12: definition has wrong shape", { # Define conditions definition_wrong_shape <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, From dcfe16ab4c52941265e7d95a3d46d57b1c7787ce Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 20 Sep 2024 15:53:00 +0000 Subject: [PATCH 24/83] style & lint --- R/derive_vars_cat.R | 42 ++++++++++++++++++--------- tests/testthat/test-derive_vars_cat.R | 3 +- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 182e16d2a..87207579f 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -22,7 +22,8 @@ #' Allows for specifying by groups, e.g. `exprs(PARAMCD)`. #' Variable must be present in both `dataset` and `definition`. #' The conditions in `definition` are applied only to those records that match `by_vars`. -#' The categorization variables are set to NA for records not matching any of the by groups in `definition`. +#' The categorization variables are set to NA for records +#' not matching any of the by groups in `definition`. #' #' #' @details @@ -127,34 +128,47 @@ #' definition = definition3, #' by_vars = exprs(VSTEST) #' ) - derive_vars_cat <- function(dataset, definition, by_vars = NULL) { # assertions assert_data_frame(dataset) assert_expr_list(definition) - if(!is.null(by_vars)){ + if (!is.null(by_vars)) { assert_vars(by_vars) - assert_data_frame(dataset, required_vars = c(admiraldev::extract_vars(definition) %>% unique(), by_vars)) - } else{ + assert_data_frame(dataset, + required_vars = c( + admiraldev::extract_vars(definition) %>% unique(), + by_vars + ) + ) + } else { assert_data_frame(dataset, required_vars = admiraldev::extract_vars(definition) %>% unique()) } # transform definition to tibble names(definition) <- NULL definition <- tryCatch( - {tibble::tribble(!!!definition)}, + { + tibble::tribble(!!!definition) + }, error = function(e) { # Catch the error and append your own message stop("Failed to convert `definition` to tribble: ", e$message) - }) + } + ) assert_data_frame(definition, required_vars = c(exprs(condition), by_vars)) - if(!is.null(by_vars)){ + if (!is.null(by_vars)) { # add condition - definition <- definition %>% mutate( - condition = extend_condition(as.character(condition), as.character(by_vars), is = !!sym(as.character(by_vars))) %>% parse_exprs() - ) %>% select(-by_vars[[1]]) + definition <- definition %>% + mutate( + condition = extend_condition(as.character(condition), + as.character(by_vars), + is = !!sym(as.character(by_vars)) + ) %>% + parse_exprs() + ) %>% + select(-by_vars[[1]]) } # extract new variable names and conditions @@ -162,9 +176,11 @@ derive_vars_cat <- function(dataset, condition <- definition[["condition"]] # warn if new variables already exist - if(any(new_col_names %in% names(dataset))){ + if (any(new_col_names %in% names(dataset))) { warning(paste("Column(s) in `definition` already exist in `dataset`.", - "Did you forget to specify `by_vars`?", sep = "\n")) + "Did you forget to specify `by_vars`?", + sep = "\n" + )) } # (re)apply the function for each new variable name and iteratively derive the categories diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index 3a75a1bb4..2b34a4b85 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -192,7 +192,8 @@ test_that("derive_vars_cat Test 11: Wrong input for by_vars", { ) expect_error(derive_vars_cat(advs, definition, by_vars = exprs(VSTEST == "Height")), - class = "assert_vars") + class = "assert_vars" + ) }) ## Test 12: definition has wrong shape ---- From 693e1a36c38287b8b6a09801bf2795ddf2932e5f Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 20 Sep 2024 17:27:47 +0000 Subject: [PATCH 25/83] update manual --- man/derive_vars_cat.Rd | 98 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 9 deletions(-) diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 841a9a25d..98ae2af82 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -4,15 +4,34 @@ \alias{derive_vars_cat} \title{Derive pair of variables} \usage{ -derive_vars_cat(dataset, definition) +derive_vars_cat(dataset, definition, by_vars = NULL) } \arguments{ -\item{dataset}{data frame containing the variables specified in the conditions} +\item{dataset}{Input dataset -\item{definition}{of condition and values defined as \code{exprs()} object. -e.g. exprs(~condition, ~AVALCAT1, ~AVALCA1N -AVAL >= 140, ">=140 cm", 1, -AVAL < 140, "<140 cm", 2)} +The variables specified by the \code{by_vars} and \code{definition} arguments are expected to be in the dataset.} + +\item{definition}{List of expressions created by: \code{exprs()}. +Must be in the format of a tribble. +Must contain: +\itemize{ +\item the column \code{condition} which evaluates to a logic in \code{dataset}. +\item at least one additional column with the new column name and the category value. +\item the column specified in \code{by_vars} (if \code{by_vars} is specified) +} + +e.g. if \code{by_vars} is not specified: +\verb{exprs(~condition, ~AVALCAT1, ~AVALCA1N AVAL >= 140, ">=140 cm", 1, AVAL < 140, "<140 cm", 2)} + +e.g. if \code{by_vars} is specified as \code{exprs(VSTEST)}: +\verb{exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N "Height", AVAL >= 140, ">=140 cm", 1, "Height", AVAL < 140, "<140 cm", 2)}} + +\item{by_vars}{list of expressions with one element. \code{NULL} by default. +Allows for specifying by groups, e.g. \code{exprs(PARAMCD)}. +Variable must be present in both \code{dataset} and \code{definition}. +The conditions in \code{definition} are applied only to those records that match \code{by_vars}. +The categorization variables are set to NA for records +not matching any of the by groups in \code{definition}.} } \value{ data frame @@ -20,6 +39,40 @@ data frame \description{ Derive pair of variables } +\details{ +If conditions are overlapping, the row order of \code{definitions} must be carefully considered. +The \strong{first} match will determine the category. +i.e. if + +\code{AVAL = 155} + +and the \code{definition} is: + +definition <- exprs( +~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +"Height", AVAL > 170, ">170 cm", 1, +"Height", AVAL <= 170, "<=170 cm", 2, +"Height", AVAL <= 160, "<=160 cm", 3 +) + +then \code{AVALCAT1} will be \code{"<=170 cm"}, as this is the first match for \code{AVAL}. +If you specify: + +definition <- exprs( +~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +"Height", AVAL <= 160, "<=160 cm", 3, +"Height", AVAL <= 170, "<=170 cm", 2, +"Height", AVAL > 170, ">170 cm", 1 +) + +Then \code{AVAL <= 160} will lead to \code{AVALCAT1 == "<=160 cm"}, +\code{AVAL} inbetween \code{160} and \code{170} will lead to \code{AVALCAT1 == "<=170 cm"}, +and \code{AVAL <= 170} will lead to \code{AVALCAT1 == ">170 cm"}. + +However, we suggest to be more explicit when defining the \code{condition}, to avoid overlap. +In this case, the middle condition should be: +\code{AVAL <= 170 & AVAL > 160} +} \examples{ advs <- tibble::tribble( @@ -48,14 +101,41 @@ advs <- tibble::tribble( definition <- exprs( ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, - VSTEST == "Height" & AVAL > 140, ">140 cm", 1, "extra1", - VSTEST == "Height" & AVAL <= 140, "<=140 cm", 2, "extra2" + VSTEST == "Height" & AVAL > 160, ">160 cm", 1, "extra1", + VSTEST == "Height" & AVAL <= 160, "<=160 cm", 2, "extra2" ) - derive_vars_cat( dataset = advs \%>\% dplyr::filter(VSTEST == "Height"), definition = definition ) +# using by_vars: +definition2 <- exprs( + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL > 160, ">160 cm", 1, + "Height", AVAL <= 160, "<=160 cm", 2, + "Weight", AVAL > 70, ">70 kg", 1, + "Weight", AVAL <= 70, "<=70 kg", 2 +) + +derive_vars_cat( + dataset = advs, + definition = definition2, + by_vars = exprs(VSTEST) +) + +# With three conditions: +definition3 <- exprs( + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL > 170, ">170 cm", 1, + "Height", AVAL <= 170 & AVAL > 160, "<=170 cm", 2, + "Height", AVAL <= 160, "<=160 cm", 3 +) + +derive_vars_cat( + dataset = advs, + definition = definition3, + by_vars = exprs(VSTEST) +) } \seealso{ General Derivation Functions for all ADaMs that returns variable appended to dataset: From c186776726f329320fed734811e2ed641c2c0403 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 20 Sep 2024 17:33:55 +0000 Subject: [PATCH 26/83] added helper documentation --- R/derive_vars_cat.R | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 87207579f..893147826 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -199,7 +199,20 @@ derive_vars_cat <- function(dataset, return(new_dataset) } -## helper +#' Extend a condition string by adding a new condition based on a variable and its value +#' +#' This internal helper function extends a condition string by appending a new condition +#' that checks if a variable equals a specific value. +#' +#' @param cond A character string representing an existing condition. +#' @param var A character string representing the name of the variable to check. +#' @param is A character string representing the value the variable should be equal to. +#' +#' @return A character string representing the extended condition. +#' @examples +#' # Extend an existing condition to include a check for 'AGE == "30"' +#' extend_condition("SEX == 'M'", "AGE", "30") +#' @noRd extend_condition <- function(cond, var, is) { paste(cond, " & ", var, " == '", is, "'", sep = "") } From 0f1fef6848bf3e1ede8db354f9c0f38d0e51f7cb Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Fri, 20 Sep 2024 19:49:50 +0000 Subject: [PATCH 27/83] update --- R/derive_vars_cat.R | 2 +- inst/WORDLIST | 2 ++ man/derive_vars_cat.Rd | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 893147826..08a44e5a2 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -53,7 +53,7 @@ #' ) #' #' Then `AVAL <= 160` will lead to `AVALCAT1 == "<=160 cm"`, -#' `AVAL` inbetween `160` and `170` will lead to `AVALCAT1 == "<=170 cm"`, +#' `AVAL` in-between `160` and `170` will lead to `AVALCAT1 == "<=170 cm"`, #' and `AVAL <= 170` will lead to `AVALCAT1 == ">170 cm"`. #' #' However, we suggest to be more explicit when defining the `condition`, to avoid overlap. diff --git a/inst/WORDLIST b/inst/WORDLIST index 708b4b52d..a573b5edf 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -241,6 +241,7 @@ ULN USUBJID USUBJIDs Upadhyay +VSTEST Vignesh WBC Walkowiak @@ -334,6 +335,7 @@ tidyverse timeframe timepart timepoint +tribble tte umol ungrouped diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 98ae2af82..099e30849 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -66,7 +66,7 @@ definition <- exprs( ) Then \code{AVAL <= 160} will lead to \code{AVALCAT1 == "<=160 cm"}, -\code{AVAL} inbetween \code{160} and \code{170} will lead to \code{AVALCAT1 == "<=170 cm"}, +\code{AVAL} in-between \code{160} and \code{170} will lead to \code{AVALCAT1 == "<=170 cm"}, and \code{AVAL <= 170} will lead to \code{AVALCAT1 == ">170 cm"}. However, we suggest to be more explicit when defining the \code{condition}, to avoid overlap. From d1db0a1626224773d8791f3c34599a6fc80619cd Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Mon, 23 Sep 2024 11:58:52 +0000 Subject: [PATCH 28/83] half way there :) --- R/derive_vars_cat.R | 2 +- inst/templates/ad_adeg.R | 61 +++++++++++++--------------------------- inst/templates/ad_adex.R | 33 ++++++++++++---------- inst/templates/ad_adpp.R | 29 ++++++------------- inst/templates/ad_advs.R | 16 ++++------- 5 files changed, 54 insertions(+), 87 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 08a44e5a2..830c7fc20 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -1,4 +1,4 @@ -#' Derive pair of variables +#' Derive Categorization Variables Like `AVALCATy` and `AVALCAyN` #' @param dataset #' `r roxygen_param_dataset(expected_vars = c("by_vars", "definition"))` #' @param definition List of expressions created by: `exprs()`. diff --git a/inst/templates/ad_adeg.R b/inst/templates/ad_adeg.R index ea0983e9e..8b91bdf16 100644 --- a/inst/templates/ad_adeg.R +++ b/inst/templates/ad_adeg.R @@ -54,44 +54,22 @@ range_lookup <- tibble::tribble( "QTLCR", 350, 450, ) -# ASSIGN AVALCAT1 -avalcat_lookup <- tibble::tribble( - ~AVALCA1N, ~AVALCAT1, - 1, "<= 450 msec", - 2, ">450<=480 msec", - 3, ">480<=500 msec", - 4, ">500 msec" +# Assign AVALCAx +avalcax_lookup <- exprs( + ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, + "QT", AVAL <= 450, "<= 450 msec", 1, + "QT", AVAL > 450 & AVAL <= 480, ">450<=480 msec", 2, + "QT", AVAL > 480 & AVAL <=500, ">480<=500 msec", 3, + "QT", AVAL > 500, ">500 msec", 4 ) - -# ASSIGN CHGCAT1 -chgcat_lookup <- tibble::tribble( - ~CHGCAT1N, ~CHGCAT1, - 1, "<= 30 msec", - 2, ">30<=60 msec", - 3, ">60 msec" +# Assign CHGCAx +chgcax_lookup <- exprs( + ~PARAMCD, ~condition, ~CHGCAT1, ~CHGCAT1N, + "QT", CHG <= 30, "<= 30 msec", 1, + "QT", CHG > 30 & CHG <= 60, ">30<=60 msec", 2, + "QT", CHG > 60, ">60 msec", 3 ) -# Here are some examples of how you can create your own functions that -# operates on vectors, which can be used in `mutate()`. Info then used for -# lookup table -format_avalca1n <- function(paramcd, aval) { - case_when( - str_detect(paramcd, "QT") & aval <= 450 ~ 1, - str_detect(paramcd, "QT") & aval > 450 & aval <= 480 ~ 2, - str_detect(paramcd, "QT") & aval > 480 & aval <= 500 ~ 3, - str_detect(paramcd, "QT") & aval > 500 ~ 4 - ) -} - -format_chgcat1n <- function(paramcd, chg) { - case_when( - str_detect(paramcd, "QT") & chg <= 30 ~ 1, - str_detect(paramcd, "QT") & chg > 30 & chg <= 60 ~ 2, - str_detect(paramcd, "QT") & chg > 60 ~ 3 - ) -} - - # Derivations ---- # Get list of ADSL vars required for derivations @@ -316,14 +294,15 @@ adeg <- adeg %>% check_type = "error" ) %>% # Derive AVALCA1N and AVALCAT1 - mutate(AVALCA1N = format_avalca1n(param = PARAMCD, aval = AVAL)) %>% - derive_vars_merged( - dataset_add = avalcat_lookup, - by_vars = exprs(AVALCA1N) + derive_vars_cat( + definition = avalcax_lookup, + by_vars = exprs(PARAMCD) ) %>% # Derive CHGCAT1N and CHGCAT1 - mutate(CHGCAT1N = format_chgcat1n(param = PARAMCD, chg = CHG)) %>% - derive_vars_merged(dataset_add = chgcat_lookup, by_vars = exprs(CHGCAT1N)) %>% + derive_vars_cat( + definition = chgcax_lookup, + by_vars = exprs(PARAMCD) + ) %>% # Derive PARAM and PARAMN derive_vars_merged( dataset_add = select(param_lookup, -EGTESTCD), diff --git a/inst/templates/ad_adex.R b/inst/templates/ad_adex.R index ca7bb17e3..96031758c 100644 --- a/inst/templates/ad_adex.R +++ b/inst/templates/ad_adex.R @@ -279,20 +279,20 @@ param_lookup <- tibble::tribble( "PDOSINT", "W2-24 dose intensity (%)", 91 ) -# User defined functions ---- -# Derive AVALCAT1 -# Here are some examples of how you can create your own functions that -# operates on vectors, which can be used in `mutate()`. -format_avalcat1 <- function(param, aval) { - case_when( - param %in% c("TDURD", "PDURD") & aval < 30 & !is.na(aval) ~ "< 30 days", - param %in% c("TDURD", "PDURD") & aval >= 30 & aval < 90 ~ ">= 30 and < 90 days", - param %in% c("TDURD", "PDURD") & aval >= 90 ~ ">=90 days", - param %in% c("TDOSE", "PDOSE") & aval < 100 & !is.na(aval) ~ "< 100 mg", - param %in% c("TDOSE", "PDOSE") & aval >= 100 ~ ">= 100 mg", - TRUE ~ NA_character_ - ) -} +# Assign AVALCATx +avalcax_lookup <- exprs( + ~PARAMCD, ~condition, ~AVALCAT1, + "TDURD", AVAL >= 90, ">= 90 days", + "TDURD", AVAL >= 30 & AVAL < 90, ">= 30 and < 90 days", + "TDURD", AVAL < 30, "< 30 days", + "PDURD", AVAL >= 90, ">= 90 days", + "PDURD", AVAL >= 30 & AVAL < 90, ">= 30 and < 90 days", + "PDURD", AVAL < 30, "< 30 days", + "TDOSE", AVAL < 100, "< 100 mg", + "TDOSE", AVAL >= 100, ">= 100 mg", + "PDOSE", AVAL < 100, "< 100 mg", + "PDOSE", AVAL >= 100, ">= 100 mg" +) adex <- adex %>% # Add PARAMN and PARAM, AVALU @@ -301,7 +301,10 @@ adex <- adex %>% by_vars = exprs(PARAMCD) ) %>% # Derive AVALCATx - mutate(AVALCAT1 = format_avalcat1(param = PARAMCD, aval = AVAL)) %>% + derive_vars_cat( + definition = avalcax_lookup, + by_vars = exprs(PARAMCD) + ) %>% # Calculate ASEQ derive_var_obs_number( new_var = ASEQ, diff --git a/inst/templates/ad_adpp.R b/inst/templates/ad_adpp.R index 544c976ae..67cf2380a 100644 --- a/inst/templates/ad_adpp.R +++ b/inst/templates/ad_adpp.R @@ -56,27 +56,15 @@ param_lookup <- tibble::tribble( "RENALCL", "RENALCL", "CLR", 22 ) -# ASSIGN AVALCAT1 -avalcat_lookup <- tibble::tribble( - ~PARAMCD, ~AVALCA1N, ~AVALCAT1, - "AUCALL", 1, "< 19", - "AUCALL", 2, ">= 19" +# Assign AVALCATx +avalcax_lookup <- exprs( + ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, + "AUCALL", AVAL < 19, "<19", 1, + "AUCALL", AVAL >= 19, ">=19", 2 ) attr(param_lookup$PPTESTCD, "label") <- "Parameter Short Name" -# User defined functions ---- - -# Here are some examples of how you can create your own functions that -# operates on vectors, which can be used in `mutate`. -format_avalcat1n <- function(param, aval) { - case_when( - param == "AUCALL" & aval < 19 ~ 1, - param == "AUCALL" & aval >= 19 ~ 2, - TRUE ~ NA_real_ - ) -} - # Derivations ---- # Get list of ADSL vars required for derivations @@ -137,9 +125,10 @@ adpp_avisit <- adpp_aval %>% TRTA = TRT01A ) %>% ## Derive AVALCA1N and AVALCAT1 ---- - mutate(AVALCA1N = format_avalcat1n(param = PARAMCD, aval = AVAL)) %>% - derive_vars_merged(dataset_add = avalcat_lookup, by_vars = exprs(PARAMCD, AVALCA1N)) - + derive_vars_cat( + definition = avalcax_lookup, + by_vars = exprs(PARAMCD) + ) # Add all ADSL variables adpp <- adpp_avisit %>% derive_vars_merged( diff --git a/inst/templates/ad_advs.R b/inst/templates/ad_advs.R index facbbc622..5f4d732b3 100644 --- a/inst/templates/ad_advs.R +++ b/inst/templates/ad_advs.R @@ -51,17 +51,12 @@ range_lookup <- tibble::tribble( "PULSE", 60, 100, 40, 110, "TEMP", 36.5, 37.5, 35, 38 ) -# # Assign AVALCAT1 -# avalcat_lookup <- tibble::tribble( -# ~PARAMCD, ~AVALCA1N, ~AVALCAT1, -# "HEIGHT", 1, ">100 cm", -# "HEIGHT", 2, "<= 100 cm" -# ) + # Assign AVALCATx avalcax_lookup <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, - PARAMCD == "HEIGHT" & AVAL > 140, ">140 cm", 1, - PARAMCD == "HEIGHT" & AVAL <= 140, "<=140 cm", 2 + ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, + "HEIGHT", AVAL > 100, ">100 cm", 1, + "HEIGHT", AVAL <= 100, "<=100 cm", 2 ) # Derivations ---- @@ -280,7 +275,8 @@ advs <- advs %>% ) %>% # Define condition and categories using derive_vars_cat derive_vars_cat( - definition = avalcax_lookup + definition = avalcax_lookup, + by_vars = exprs(PARAMCD) ) %>% # Derive PARAM and PARAMN derive_vars_merged(dataset_add = select(param_lookup, -VSTESTCD), by_vars = exprs(PARAMCD)) From 1dedbb71d2cf34f32f6fee0522a856b657b08ec2 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Mon, 23 Sep 2024 13:34:15 +0000 Subject: [PATCH 29/83] clean up ad_adpc --- inst/templates/ad_adpc.R | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/inst/templates/ad_adpc.R b/inst/templates/ad_adpc.R index 850bf9808..0678b7e30 100644 --- a/inst/templates/ad_adpc.R +++ b/inst/templates/ad_adpc.R @@ -41,18 +41,6 @@ param_lookup <- tibble::tribble( "DOSE", "DOSE", "Xanomeline Patch Dose", 2, ) -# ---- User defined functions ---- - -# Here is an example of how you can create your own function that -# operates on vectors, which can be used in `mutate`. -format_avalcat1n <- function(param, aval) { - case_when( - param == "PKCONC" & aval < 1 ~ 1, - param == "PKCONC" & aval >= 1 ~ 2, - T ~ NA_real_ - ) -} - # ---- Derivations ---- # Get list of ADSL vars required for derivations From 3f6233df3c532a92f7be833e39cf5100d12f6363 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Mon, 23 Sep 2024 15:12:25 +0000 Subject: [PATCH 30/83] UPDATE VIGNETTES --- man/derive_vars_cat.Rd | 4 +-- vignettes/adsl.Rmd | 52 +++++++++++++++++------------------- vignettes/bds_exposure.Rmd | 28 ++++++++++--------- vignettes/bds_finding.Rmd | 25 +++++++---------- vignettes/generic.Rmd | 1 + vignettes/questionnaires.Rmd | 45 ++++++++++++++----------------- 6 files changed, 72 insertions(+), 83 deletions(-) diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 099e30849..80f1d1531 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/derive_vars_cat.R \name{derive_vars_cat} \alias{derive_vars_cat} -\title{Derive pair of variables} +\title{Derive Categorization Variables Like \code{AVALCATy} and \code{AVALCAyN}} \usage{ derive_vars_cat(dataset, definition, by_vars = NULL) } @@ -37,7 +37,7 @@ not matching any of the by groups in \code{definition}.} data frame } \description{ -Derive pair of variables +Derive Categorization Variables Like \code{AVALCATy} and \code{AVALCAyN} } \details{ If conditions are overlapping, the row order of \code{definitions} must be carefully considered. diff --git a/vignettes/adsl.Rmd b/vignettes/adsl.Rmd index 0fd964896..5b60e47c5 100644 --- a/vignettes/adsl.Rmd +++ b/vignettes/adsl.Rmd @@ -677,41 +677,37 @@ dataset_vignette( Numeric and categorical variables (`AGE`, `RACE`, `COUNTRY`, etc.) may need to be grouped to perform the required analysis. -`{admiral}` does not **currently** have functionality to assist with all required groupings. So, the user will often need to create his/her own function to meet his/her study requirement. - -For example, if - -- `AGEGR1` is required to categorize `AGE` into `<18`, `18-64` and `>64`, or -- `REGION1` is required to categorize `COUNTRY` in `North America`, `Rest of the World`, - -the user defined functions would look like the following: +`{admiral}` provides the `derive_vars_cat` function to create such groups. +However, one needs to be careful when considering the order of the conditions in the lookup table. +The category is assigned based on the first match. +That means *catch-all* conditions must come after specific conditions, e.g. `!is.na(AGE)` +must come after `AGE < 18`. ```{r eval=TRUE} -format_agegr1 <- function(var_input) { - case_when( - var_input < 18 ~ "<18", - between(var_input, 18, 64) ~ "18-64", - var_input > 64 ~ ">64", - TRUE ~ "Missing" - ) -} +# create lookup tables +agegr1_lookup <- exprs( + ~condition, ~AGEGR1, + AGE < 18, "<18", + between(AGE, 18, 64), "18-64", + AGE > 64, ">64", + is.na(AGE), "Missing" +) -format_region1 <- function(var_input) { - case_when( - var_input %in% c("CAN", "USA") ~ "North America", - !is.na(var_input) ~ "Rest of the World", - TRUE ~ "Missing" - ) -} +region1_lookup <- exprs( + ~condition, ~REGION1, + COUNTRY %in% c("CAN", "USA"), "North America", + !is.na(COUNTRY), "Rest of the World", + is.na(COUNTRY), "Missing" +) ``` -These functions are then used in a `mutate()` statement to derive the required grouping variables: - ```{r eval=TRUE} adsl <- adsl %>% - mutate( - AGEGR1 = format_agegr1(AGE), - REGION1 = format_region1(COUNTRY) + derive_vars_cat( + definition = agegr1_lookup + ) %>% + derive_vars_cat( + definition = region1_lookup ) ``` diff --git a/vignettes/bds_exposure.Rmd b/vignettes/bds_exposure.Rmd index 8e9314741..65d08a3f6 100644 --- a/vignettes/bds_exposure.Rmd +++ b/vignettes/bds_exposure.Rmd @@ -545,21 +545,25 @@ the join depending on your lookup/metadata table. ## Derive Categorization Variables (`AVALCATx`) {#cat} -`{admiral}` does not currently have a generic function to aid in assigning `AVALCATx`/ -`AVALCAxN` values. Below is a simple example of how these values may be -assigned using the `dplyr::mutate` function: +We can use the `derive_vars_cat` function to derive the categorization variables. ```{r eval=TRUE, echo=TRUE} +avalcax_lookup <- exprs( + ~PARAMCD, ~condition, ~AVALCAT1, + "TDURD", AVAL >= 90, ">= 90 days", + "TDURD", AVAL >= 30 & AVAL < 90, ">= 30 and < 90 days", + "TDURD", AVAL < 30, "< 30 days", + "TDOSE", AVAL < 1000, "< 1000 mg", + "TDOSE", AVAL >= 1000, ">= 1000 mg", + "TPDOSE", AVAL < 1000, "< 1000 mg", + "TPDOSE", AVAL >= 1000, ">= 1000 mg" +) + + adex <- adex %>% - mutate( - AVALCAT1 = case_when( - PARAMCD %in% c("TDURD") & AVAL < 30 ~ "< 30 days", - PARAMCD %in% c("TDURD") & AVAL >= 30 & AVAL < 90 ~ ">= 30 and < 90 days", - PARAMCD %in% c("TDURD") & AVAL >= 90 ~ ">=90 days", - PARAMCD %in% c("TDOSE", "TPDOSE") & AVAL < 1000 ~ "< 1000 mg", - PARAMCD %in% c("TDOSE", "TPDOSE") & AVAL >= 1000 ~ ">= 1000 mg", - TRUE ~ NA_character_ - ) + derive_vars_cat( + definition = avalcax_lookup, + by_vars = exprs(PARAMCD) ) ``` diff --git a/vignettes/bds_finding.Rmd b/vignettes/bds_finding.Rmd index 59c286847..f21173442 100644 --- a/vignettes/bds_finding.Rmd +++ b/vignettes/bds_finding.Rmd @@ -848,26 +848,19 @@ dataset_vignette( ## Derive Categorization Variables (`AVALCATx`) {#cat} -Admiral does not currently have a generic function to aid in assigning `AVALCATy`/ -`AVALCAvN` values. Below is a simple example of how these values may be -assigned: +We can use the `derive_vars_cat` function to derive the categorization variables. ```{r eval=TRUE} -avalcat_lookup <- tibble::tribble( - ~PARAMCD, ~AVALCA1N, ~AVALCAT1, - "HEIGHT", 1, ">140 cm", - "HEIGHT", 2, "<= 140 cm" +avalcat_lookup <- exprs( + ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, + "HEIGHT", AVAL > 140, ">140 cm", 1, + "HEIGHT", AVAL <= 140, "<= 140 cm", 2 ) - -format_avalcat1n <- function(param, aval) { - case_when( - param == "HEIGHT" & aval > 140 ~ 1, - param == "HEIGHT" & aval <= 140 ~ 2 - ) -} - advs <- advs %>% - mutate(AVALCA1N = format_avalcat1n(param = PARAMCD, aval = AVAL)) %>% + derive_vars_cat( + definition = avalcat_lookup, + by_vars = exprs(PARAMCD) + ) %>% derive_vars_merged( avalcat_lookup, by = exprs(PARAMCD, AVALCA1N) diff --git a/vignettes/generic.Rmd b/vignettes/generic.Rmd index 9450dc529..6cfb6bf45 100644 --- a/vignettes/generic.Rmd +++ b/vignettes/generic.Rmd @@ -72,6 +72,7 @@ generic_derivations <- tibble::tribble( "derive_vars_merged()", "selection", "variables", "single", "derive_vars_extreme_event()", "selection", "variables", "multiple", "derive_vars_computed()", "computation", "variables", "single", + "derive_vars_cat()", "selection", "variables", "single", "derive_extreme_event()", "selection", "records", "multiple", "derive_extreme_records()", "selection", "records", "single", "derive_param_computed()", "computation", "records", "single", diff --git a/vignettes/questionnaires.Rmd b/vignettes/questionnaires.Rmd index 18edb6fc4..165318f0f 100644 --- a/vignettes/questionnaires.Rmd +++ b/vignettes/questionnaires.Rmd @@ -251,26 +251,25 @@ and `EVNTDESC`, it makes sense to create a separate time to event dataset for them. However, it might be useful to create flags or categorization variables in `ADQS`. For example: ```{r} +# Create AVALCATx lookup table +avalcat_lookup <- exprs( + ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCAT1N, + "GDS02TS", AVAL <= 5, "Normal", 0L, + "GDS02TS", AVAL <= 10 & AVAL > 5, "Possible Depression", 1L, + "GDS02TS", AVAL > 10, "Likely Depression", 2L +) +# Create CHGCAT1 lookup table +chgcat_lookup <- exprs( + ~condition, ~CHGCAT1, + AVALCAT1N > BASECA1N, "WORSENED", + AVALCAT1N == BASECA1N, "NO CHANGE", + AVALCAT1N < BASECA1N, "IMPROVED" +) + adgdssf <- adgdssf %>% - mutate( - AVALCAT1 = if_else( - PARAMCD == "GDS02TS", - case_when( - AVAL <= 5 ~ "Normal", - AVAL <= 10 ~ "Possible Depression", - AVAL > 10 ~ "Likely Depression" - ), - NA_character_ - ), - AVALCAT1N = if_else( - PARAMCD == "GDS02TS", - case_when( - AVAL <= 5 ~ 0L, - AVAL <= 10 ~ 1L, - AVAL > 10 ~ 2L - ), - NA_integer_ - ) + derive_vars_cat( + definition = avalcat_lookup, + by_vars = exprs(PARAMCD) ) %>% derive_var_base( by_vars = exprs(STUDYID, USUBJID, PARAMCD), @@ -282,12 +281,8 @@ adgdssf <- adgdssf %>% source_var = AVALCAT1N, new_var = BASECA1N ) %>% - mutate( - CHGCAT1 = case_when( - AVALCAT1N > BASECA1N ~ "WORSENED", - AVALCAT1N == BASECA1N ~ "NO CHANGE", - AVALCAT1N < BASECA1N ~ "IMPROVED", - ) + derive_vars_cat( + definition = chgcat_lookup ) ``` From 4267dfcd6b72b1e39a304d3732ed6c513b5b3e44 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Mon, 23 Sep 2024 15:26:40 +0000 Subject: [PATCH 31/83] fix error --- vignettes/bds_finding.Rmd | 4 ---- 1 file changed, 4 deletions(-) diff --git a/vignettes/bds_finding.Rmd b/vignettes/bds_finding.Rmd index f21173442..f537f4eb9 100644 --- a/vignettes/bds_finding.Rmd +++ b/vignettes/bds_finding.Rmd @@ -860,10 +860,6 @@ advs <- advs %>% derive_vars_cat( definition = avalcat_lookup, by_vars = exprs(PARAMCD) - ) %>% - derive_vars_merged( - avalcat_lookup, - by = exprs(PARAMCD, AVALCA1N) ) ``` From fa21e811638ab5fcab7f7376f1b46c15270ff10b Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Mon, 23 Sep 2024 15:55:28 +0000 Subject: [PATCH 32/83] styler --- inst/templates/ad_adeg.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/templates/ad_adeg.R b/inst/templates/ad_adeg.R index 8b91bdf16..2f6d5158a 100644 --- a/inst/templates/ad_adeg.R +++ b/inst/templates/ad_adeg.R @@ -59,7 +59,7 @@ avalcax_lookup <- exprs( ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, "QT", AVAL <= 450, "<= 450 msec", 1, "QT", AVAL > 450 & AVAL <= 480, ">450<=480 msec", 2, - "QT", AVAL > 480 & AVAL <=500, ">480<=500 msec", 3, + "QT", AVAL > 480 & AVAL <= 500, ">480<=500 msec", 3, "QT", AVAL > 500, ">500 msec", 4 ) # Assign CHGCAx From 0dbbe676c44a74cb6eb4be80e035122b825e6b64 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 07:32:02 +0200 Subject: [PATCH 33/83] Update vignettes/adsl.Rmd Co-authored-by: Ben Straub --- vignettes/adsl.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/adsl.Rmd b/vignettes/adsl.Rmd index 5b60e47c5..ab693a795 100644 --- a/vignettes/adsl.Rmd +++ b/vignettes/adsl.Rmd @@ -677,7 +677,7 @@ dataset_vignette( Numeric and categorical variables (`AGE`, `RACE`, `COUNTRY`, etc.) may need to be grouped to perform the required analysis. -`{admiral}` provides the `derive_vars_cat` function to create such groups. +`{admiral}` provides the `derive_vars_cat()` function to create such groups. However, one needs to be careful when considering the order of the conditions in the lookup table. The category is assigned based on the first match. That means *catch-all* conditions must come after specific conditions, e.g. `!is.na(AGE)` From 4fc3180692488665b91de06bfc9640f4b6f78c79 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 07:32:11 +0200 Subject: [PATCH 34/83] Update vignettes/bds_exposure.Rmd Co-authored-by: Ben Straub --- vignettes/bds_exposure.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/bds_exposure.Rmd b/vignettes/bds_exposure.Rmd index 65d08a3f6..65133c7f1 100644 --- a/vignettes/bds_exposure.Rmd +++ b/vignettes/bds_exposure.Rmd @@ -545,7 +545,7 @@ the join depending on your lookup/metadata table. ## Derive Categorization Variables (`AVALCATx`) {#cat} -We can use the `derive_vars_cat` function to derive the categorization variables. +We can use the `derive_vars_cat()` function to derive the categorization variables. ```{r eval=TRUE, echo=TRUE} avalcax_lookup <- exprs( From d09a9c7d71ad5230d405246d1f719272c81ae38c Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 07:33:07 +0200 Subject: [PATCH 35/83] Update R/derive_vars_cat.R Co-authored-by: Ben Straub --- R/derive_vars_cat.R | 1 - 1 file changed, 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 830c7fc20..09f0e6bc6 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -131,7 +131,6 @@ derive_vars_cat <- function(dataset, definition, by_vars = NULL) { - # assertions assert_data_frame(dataset) assert_expr_list(definition) if (!is.null(by_vars)) { From daa6eadbd697ea46e5258d1ee7d581b0ad478f71 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 07:37:02 +0200 Subject: [PATCH 36/83] Update R/derive_vars_cat.R --- R/derive_vars_cat.R | 1 - 1 file changed, 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 09f0e6bc6..bde24044d 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -186,7 +186,6 @@ derive_vars_cat <- function(dataset, new_dataset <- reduce(new_col_names, function(.data, col_name) { # extract conditions values <- definition[[col_name]] - # extract values .data %>% mutate(!!sym(col_name) := eval(rlang::call2( From c2c220743ad1c7c05baa2a528f3379128ee6cc50 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 07:38:22 +0200 Subject: [PATCH 37/83] Update NEWS.md --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 26c0a9827..4ca8e4477 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,7 @@ ## New Features - New function `derive_vars_cat()` for deriving pairs of variables or more, e.g. -`MCRITyML` & `MCRITyMN`. (#2480) +`AVALCATx` & `AVALCAyN`. (#2480) - New function `derive_vars_crit_flag()` for deriving criterion flag variables (`CRITy`, `CRITyFL`, `CRITyFLN`). (#2468) From acbf169e46d2a1dd0092edf91cc435b9099f8cf4 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 07:46:08 +0200 Subject: [PATCH 38/83] Update R/derive_vars_cat.R Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- R/derive_vars_cat.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index bde24044d..a30cbabc8 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -66,6 +66,8 @@ #' @export #' #' @examples +#' library(dplyr) +#' library(tibble) #' #' advs <- tibble::tribble( #' ~USUBJID, ~VSTEST, ~AVAL, From 33ffc1275ddf84c195677ab955ec3029019cf9f3 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 07:48:27 +0200 Subject: [PATCH 39/83] Update inst/templates/ad_advs.R --- inst/templates/ad_advs.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/templates/ad_advs.R b/inst/templates/ad_advs.R index 5f4d732b3..3b50dec8f 100644 --- a/inst/templates/ad_advs.R +++ b/inst/templates/ad_advs.R @@ -264,7 +264,7 @@ advs <- advs %>% TRTA = TRT01A ) -# Get ASEQ and AVALCATx and add PARAM/PARAMN ---- +## Get ASEQ and AVALCATx and add PARAM/PARAMN ---- advs <- advs %>% # Calculate ASEQ derive_var_obs_number( From cc210f158aebdaccde1f63f0c5bc0745fab5416e Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 07:58:37 +0000 Subject: [PATCH 40/83] update --- R/derive_vars_cat.R | 88 +++++++++++++++++++++++++++----------- inst/WORDLIST | 4 -- man/derive_vars_cat.Rd | 97 +++++++++++++++++++++++++++++------------- 3 files changed, 130 insertions(+), 59 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index a30cbabc8..b5740f98c 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -2,21 +2,32 @@ #' @param dataset #' `r roxygen_param_dataset(expected_vars = c("by_vars", "definition"))` #' @param definition List of expressions created by: `exprs()`. -#' Must be in the format of a tribble. +#' Must be in rectangular format and specified using the same syntax as when creating +#' a `tibble` using the `tribble()` function. +#' The `definition` object it will be converted to a `tibble` using the `tribble()` function. +#' #' Must contain: #' - the column `condition` which evaluates to a logic in `dataset`. #' - at least one additional column with the new column name and the category value. #' - the column specified in `by_vars` (if `by_vars` is specified) #' #' e.g. if `by_vars` is not specified: -#' `exprs(~condition, ~AVALCAT1, ~AVALCA1N -#' AVAL >= 140, ">=140 cm", 1, -#' AVAL < 140, "<140 cm", 2)` +#' +#' ```{r} +#' #| eval: false +#' exprs(~condition, ~AVALCAT1, ~AVALCA1N, +#' AVAL >= 140, ">=140 cm", 1, +#' AVAL < 140, "<140 cm", 2) +#' ``` #' #' e.g. if `by_vars` is specified as `exprs(VSTEST)`: -#' `exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N -#' "Height", AVAL >= 140, ">=140 cm", 1, -#' "Height", AVAL < 140, "<140 cm", 2)` +#' +#' ```{r} +#' #| eval: false +#' exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL >= 140, ">=140 cm", 1, +#' "Height", AVAL < 140, "<140 cm", 2) +#' ``` #' #' @param by_vars list of expressions with one element. `NULL` by default. #' Allows for specifying by groups, e.g. `exprs(PARAMCD)`. @@ -35,22 +46,27 @@ #' #' and the `definition` is: #' +#' ```{r} +#' #| eval: false #' definition <- exprs( #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, #' "Height", AVAL > 170, ">170 cm", 1, #' "Height", AVAL <= 170, "<=170 cm", 2, #' "Height", AVAL <= 160, "<=160 cm", 3 #' ) -#' +#' ``` #' then `AVALCAT1` will be `"<=170 cm"`, as this is the first match for `AVAL`. #' If you specify: #' +#' ```{r} +#' #| eval: false #' definition <- exprs( #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, #' "Height", AVAL <= 160, "<=160 cm", 3, #' "Height", AVAL <= 170, "<=170 cm", 2, #' "Height", AVAL > 170, ">170 cm", 1 #' ) +#' ``` #' #' Then `AVAL <= 160` will lead to `AVALCAT1 == "<=160 cm"`, #' `AVAL` in-between `160` and `170` will lead to `AVALCAT1 == "<=170 cm"`, @@ -74,23 +90,11 @@ #' "01-701-1015", "Height", 147.32, #' "01-701-1015", "Weight", 53.98, #' "01-701-1023", "Height", 162.56, -#' "01-701-1023", "Weight", 78.47, -#' "01-701-1028", "Height", 177.8, -#' "01-701-1028", "Weight", 98.88, +#' "01-701-1023", "Weight", NA, +#' "01-701-1028", "Height", NA, +#' "01-701-1028", "Weight", NA, #' "01-701-1033", "Height", 175.26, -#' "01-701-1033", "Weight", 88.45, -#' "01-701-1034", "Height", 154.94, -#' "01-701-1034", "Weight", 63.5, -#' "01-701-1047", "Height", 148.59, -#' "01-701-1047", "Weight", 66.23, -#' "01-701-1097", "Height", 168.91, -#' "01-701-1097", "Weight", 78.02, -#' "01-701-1111", "Height", 158.24, -#' "01-701-1111", "Weight", 60.33, -#' "01-701-1115", "Height", 181.61, -#' "01-701-1115", "Weight", 78.7, -#' "01-701-1118", "Height", 180.34, -#' "01-701-1118", "Weight", 71.67 +#' "01-701-1033", "Weight", 88.45 #' ) #' #' definition <- exprs( @@ -99,7 +103,7 @@ #' VSTEST == "Height" & AVAL <= 160, "<=160 cm", 2, "extra2" #' ) #' derive_vars_cat( -#' dataset = advs %>% dplyr::filter(VSTEST == "Height"), +#' dataset = advs, #' definition = definition #' ) #' # using by_vars: @@ -130,6 +134,40 @@ #' definition = definition3, #' by_vars = exprs(VSTEST) #' ) +#' +#' # Let's derive both the MCRITyML and the MCRITyMN variables +#' adlb <- tibble::tribble( +#' ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ULN, ~LLN, +#' "01-701-1015", "ALT", 150, "U/L", 40, 10, +#' "01-701-1023", "ALT", 70, "U/L", 40, 10, +#' "01-701-1036", "ALT", 130, "U/L", 40, 10, +#' "01-701-1048", "ALT", 30, "U/L", 40, 10, +#' "01-701-1015", "AST", 50, "U/L", 35, 5 +#' ) +#' +#' # Deriving MCRIT1ML: ALT > 3x ULN +#' definition_mcrit1ml <- exprs( +#' ~PARAM, ~condition, ~MCRIT1ML, +#' "ALT", AVAL > 3 * ULN, "Y", +#' "ALT", AVAL <= 3 * ULN, "N" +#' ) +#' +#' # Deriving MCRIT1MN: ALT < LLN +#' definition_mcrit1mn <- exprs( +#' ~PARAM, ~condition, ~MCRIT1MN, +#' "ALT", AVAL > ULN, "Y", +#' "ALT", AVAL <= ULN, "N" +#' ) +#' +#' adlb %>% +#' derive_vars_cat( +#' definition = definition_mcrit1ml, +#' by_vars = exprs(PARAM) +#' ) %>% +#' derive_vars_cat( +#' definition = definition_mcrit1mn, +#' by_vars = exprs(PARAM) +#' ) derive_vars_cat <- function(dataset, definition, by_vars = NULL) { diff --git a/inst/WORDLIST b/inst/WORDLIST index a573b5edf..23746554a 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -30,8 +30,6 @@ ASTDTM ATC ATOXGR AVAL -AVALCA -AVALCAT Abercrombie Akinyi Alanine @@ -241,7 +239,6 @@ ULN USUBJID USUBJIDs Upadhyay -VSTEST Vignesh WBC Walkowiak @@ -335,7 +332,6 @@ tidyverse timeframe timepart timepoint -tribble tte umol ungrouped diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 80f1d1531..2a7ca9657 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -12,7 +12,10 @@ derive_vars_cat(dataset, definition, by_vars = NULL) The variables specified by the \code{by_vars} and \code{definition} arguments are expected to be in the dataset.} \item{definition}{List of expressions created by: \code{exprs()}. -Must be in the format of a tribble. +Must be in rectangular format and specified using the same syntax as when creating +a \code{tibble} using the \code{tribble()} function. +The \code{definition} object it will be converted to a \code{tibble} using the \code{tribble()} function. + Must contain: \itemize{ \item the column \code{condition} which evaluates to a logic in \code{dataset}. @@ -21,10 +24,18 @@ Must contain: } e.g. if \code{by_vars} is not specified: -\verb{exprs(~condition, ~AVALCAT1, ~AVALCA1N AVAL >= 140, ">=140 cm", 1, AVAL < 140, "<140 cm", 2)} + +\if{html}{\out{
}}\preformatted{exprs(~condition, ~AVALCAT1, ~AVALCA1N, + AVAL >= 140, ">=140 cm", 1, + AVAL < 140, "<140 cm", 2) +}\if{html}{\out{
}} e.g. if \code{by_vars} is specified as \code{exprs(VSTEST)}: -\verb{exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N "Height", AVAL >= 140, ">=140 cm", 1, "Height", AVAL < 140, "<140 cm", 2)}} + +\if{html}{\out{
}}\preformatted{exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 140, ">=140 cm", 1, + "Height", AVAL < 140, "<140 cm", 2) +}\if{html}{\out{
}}} \item{by_vars}{list of expressions with one element. \code{NULL} by default. Allows for specifying by groups, e.g. \code{exprs(PARAMCD)}. @@ -48,22 +59,24 @@ i.e. if and the \code{definition} is: -definition <- exprs( -~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, -"Height", AVAL > 170, ">170 cm", 1, -"Height", AVAL <= 170, "<=170 cm", 2, -"Height", AVAL <= 160, "<=160 cm", 3 +\if{html}{\out{
}}\preformatted{definition <- exprs( + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL > 170, ">170 cm", 1, + "Height", AVAL <= 170, "<=170 cm", 2, + "Height", AVAL <= 160, "<=160 cm", 3 ) +}\if{html}{\out{
}} then \code{AVALCAT1} will be \code{"<=170 cm"}, as this is the first match for \code{AVAL}. If you specify: -definition <- exprs( -~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, -"Height", AVAL <= 160, "<=160 cm", 3, -"Height", AVAL <= 170, "<=170 cm", 2, -"Height", AVAL > 170, ">170 cm", 1 +\if{html}{\out{
}}\preformatted{definition <- exprs( + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL <= 160, "<=160 cm", 3, + "Height", AVAL <= 170, "<=170 cm", 2, + "Height", AVAL > 170, ">170 cm", 1 ) +}\if{html}{\out{
}} Then \code{AVAL <= 160} will lead to \code{AVALCAT1 == "<=160 cm"}, \code{AVAL} in-between \code{160} and \code{170} will lead to \code{AVALCAT1 == "<=170 cm"}, @@ -74,29 +87,19 @@ In this case, the middle condition should be: \code{AVAL <= 170 & AVAL > 160} } \examples{ +library(dplyr) +library(tibble) advs <- tibble::tribble( ~USUBJID, ~VSTEST, ~AVAL, "01-701-1015", "Height", 147.32, "01-701-1015", "Weight", 53.98, "01-701-1023", "Height", 162.56, - "01-701-1023", "Weight", 78.47, - "01-701-1028", "Height", 177.8, - "01-701-1028", "Weight", 98.88, + "01-701-1023", "Weight", NA, + "01-701-1028", "Height", NA, + "01-701-1028", "Weight", NA, "01-701-1033", "Height", 175.26, - "01-701-1033", "Weight", 88.45, - "01-701-1034", "Height", 154.94, - "01-701-1034", "Weight", 63.5, - "01-701-1047", "Height", 148.59, - "01-701-1047", "Weight", 66.23, - "01-701-1097", "Height", 168.91, - "01-701-1097", "Weight", 78.02, - "01-701-1111", "Height", 158.24, - "01-701-1111", "Weight", 60.33, - "01-701-1115", "Height", 181.61, - "01-701-1115", "Weight", 78.7, - "01-701-1118", "Height", 180.34, - "01-701-1118", "Weight", 71.67 + "01-701-1033", "Weight", 88.45 ) definition <- exprs( @@ -105,7 +108,7 @@ definition <- exprs( VSTEST == "Height" & AVAL <= 160, "<=160 cm", 2, "extra2" ) derive_vars_cat( - dataset = advs \%>\% dplyr::filter(VSTEST == "Height"), + dataset = advs, definition = definition ) # using by_vars: @@ -136,6 +139,40 @@ derive_vars_cat( definition = definition3, by_vars = exprs(VSTEST) ) + +# Let's derive both the MCRITyML and the MCRITyMN variables +adlb <- tibble::tribble( + ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ULN, ~LLN, + "01-701-1015", "ALT", 150, "U/L", 40, 10, + "01-701-1023", "ALT", 70, "U/L", 40, 10, + "01-701-1036", "ALT", 130, "U/L", 40, 10, + "01-701-1048", "ALT", 30, "U/L", 40, 10, + "01-701-1015", "AST", 50, "U/L", 35, 5 +) + +# Deriving MCRIT1ML: ALT > 3x ULN +definition_mcrit1ml <- exprs( + ~PARAM, ~condition, ~MCRIT1ML, + "ALT", AVAL > 3 * ULN, "Y", + "ALT", AVAL <= 3 * ULN, "N" +) + +# Deriving MCRIT1MN: ALT < LLN +definition_mcrit1mn <- exprs( + ~PARAM, ~condition, ~MCRIT1MN, + "ALT", AVAL > ULN, "Y", + "ALT", AVAL <= ULN, "N" +) + +adlb \%>\% + derive_vars_cat( + definition = definition_mcrit1ml, + by_vars = exprs(PARAM) + ) \%>\% + derive_vars_cat( + definition = definition_mcrit1mn, + by_vars = exprs(PARAM) + ) } \seealso{ General Derivation Functions for all ADaMs that returns variable appended to dataset: From bb7494312e3bea9b1a6c597b34a0461af4f00d3e Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 10:01:21 +0200 Subject: [PATCH 41/83] Update vignettes/bds_finding.Rmd --- vignettes/bds_finding.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/bds_finding.Rmd b/vignettes/bds_finding.Rmd index f537f4eb9..f32c9b8ea 100644 --- a/vignettes/bds_finding.Rmd +++ b/vignettes/bds_finding.Rmd @@ -848,7 +848,7 @@ dataset_vignette( ## Derive Categorization Variables (`AVALCATx`) {#cat} -We can use the `derive_vars_cat` function to derive the categorization variables. +We can use the `derive_vars_cat()` function to derive the categorization variables. ```{r eval=TRUE} avalcat_lookup <- exprs( From f4ec1154a5b486e070857d78af4c352731d4bfea Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 08:36:56 +0000 Subject: [PATCH 42/83] update style of tibbles --- R/derive_vars_cat.R | 86 +++++++++++++++++++++--------------------- man/derive_vars_cat.Rd | 86 +++++++++++++++++++++--------------------- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index b5740f98c..09c0ce3fe 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -15,18 +15,18 @@ #' #' ```{r} #' #| eval: false -#' exprs(~condition, ~AVALCAT1, ~AVALCA1N, -#' AVAL >= 140, ">=140 cm", 1, -#' AVAL < 140, "<140 cm", 2) +#' exprs(~condition, ~AVALCAT1, ~AVALCA1N, +#' AVAL >= 140, ">=140 cm", 1, +#' AVAL < 140, "<140 cm", 2) #' ``` #' #' e.g. if `by_vars` is specified as `exprs(VSTEST)`: #' #' ```{r} #' #| eval: false -#' exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, -#' "Height", AVAL >= 140, ">=140 cm", 1, -#' "Height", AVAL < 140, "<140 cm", 2) +#' exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL >= 140, ">=140 cm", 1, +#' "Height", AVAL < 140, "<140 cm", 2) #' ``` #' #' @param by_vars list of expressions with one element. `NULL` by default. @@ -49,10 +49,10 @@ #' ```{r} #' #| eval: false #' definition <- exprs( -#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, -#' "Height", AVAL > 170, ">170 cm", 1, -#' "Height", AVAL <= 170, "<=170 cm", 2, -#' "Height", AVAL <= 160, "<=160 cm", 3 +#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL > 170, ">170 cm", 1, +#' "Height", AVAL <= 170, "<=170 cm", 2, +#' "Height", AVAL <= 160, "<=160 cm", 3 #' ) #' ``` #' then `AVALCAT1` will be `"<=170 cm"`, as this is the first match for `AVAL`. @@ -61,10 +61,10 @@ #' ```{r} #' #| eval: false #' definition <- exprs( -#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, -#' "Height", AVAL <= 160, "<=160 cm", 3, -#' "Height", AVAL <= 170, "<=170 cm", 2, -#' "Height", AVAL > 170, ">170 cm", 1 +#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL <= 160, "<=160 cm", 3, +#' "Height", AVAL <= 170, "<=170 cm", 2, +#' "Height", AVAL > 170, ">170 cm", 1 #' ) #' ``` #' @@ -86,21 +86,21 @@ #' library(tibble) #' #' advs <- tibble::tribble( -#' ~USUBJID, ~VSTEST, ~AVAL, +#' ~USUBJID, ~VSTEST, ~AVAL, #' "01-701-1015", "Height", 147.32, -#' "01-701-1015", "Weight", 53.98, +#' "01-701-1015", "Weight", 53.98, #' "01-701-1023", "Height", 162.56, -#' "01-701-1023", "Weight", NA, -#' "01-701-1028", "Height", NA, -#' "01-701-1028", "Weight", NA, +#' "01-701-1023", "Weight", NA, +#' "01-701-1028", "Height", NA, +#' "01-701-1028", "Weight", NA, #' "01-701-1033", "Height", 175.26, -#' "01-701-1033", "Weight", 88.45 +#' "01-701-1033", "Weight", 88.45 #' ) #' #' definition <- exprs( -#' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, -#' VSTEST == "Height" & AVAL > 160, ">160 cm", 1, "extra1", -#' VSTEST == "Height" & AVAL <= 160, "<=160 cm", 2, "extra2" +#' ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, +#' VSTEST == "Height" & AVAL > 160, ">160 cm", 1, "extra1", +#' VSTEST == "Height" & AVAL <= 160, "<=160 cm", 2, "extra2" #' ) #' derive_vars_cat( #' dataset = advs, @@ -108,11 +108,11 @@ #' ) #' # using by_vars: #' definition2 <- exprs( -#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, -#' "Height", AVAL > 160, ">160 cm", 1, -#' "Height", AVAL <= 160, "<=160 cm", 2, -#' "Weight", AVAL > 70, ">70 kg", 1, -#' "Weight", AVAL <= 70, "<=70 kg", 2 +#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL > 160, ">160 cm", 1, +#' "Height", AVAL <= 160, "<=160 cm", 2, +#' "Weight", AVAL > 70, ">70 kg", 1, +#' "Weight", AVAL <= 70, "<=70 kg", 2 #' ) #' #' derive_vars_cat( @@ -123,10 +123,10 @@ #' #' # With three conditions: #' definition3 <- exprs( -#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, -#' "Height", AVAL > 170, ">170 cm", 1, -#' "Height", AVAL <= 170 & AVAL > 160, "<=170 cm", 2, -#' "Height", AVAL <= 160, "<=160 cm", 3 +#' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, +#' "Height", AVAL > 170, ">170 cm", 1, +#' "Height", AVAL <= 170 & AVAL > 160, "<=170 cm", 2, +#' "Height", AVAL <= 160, "<=160 cm", 3 #' ) #' #' derive_vars_cat( @@ -137,26 +137,26 @@ #' #' # Let's derive both the MCRITyML and the MCRITyMN variables #' adlb <- tibble::tribble( -#' ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ULN, ~LLN, -#' "01-701-1015", "ALT", 150, "U/L", 40, 10, -#' "01-701-1023", "ALT", 70, "U/L", 40, 10, -#' "01-701-1036", "ALT", 130, "U/L", 40, 10, -#' "01-701-1048", "ALT", 30, "U/L", 40, 10, -#' "01-701-1015", "AST", 50, "U/L", 35, 5 +#' ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ULN, ~LLN, +#' "01-701-1015", "ALT", 150, "U/L", 40, 10, +#' "01-701-1023", "ALT", 70, "U/L", 40, 10, +#' "01-701-1036", "ALT", 130, "U/L", 40, 10, +#' "01-701-1048", "ALT", 30, "U/L", 40, 10, +#' "01-701-1015", "AST", 50, "U/L", 35, 5 #' ) #' #' # Deriving MCRIT1ML: ALT > 3x ULN #' definition_mcrit1ml <- exprs( -#' ~PARAM, ~condition, ~MCRIT1ML, -#' "ALT", AVAL > 3 * ULN, "Y", -#' "ALT", AVAL <= 3 * ULN, "N" +#' ~PARAM, ~condition, ~MCRIT1ML, +#' "ALT", AVAL > 3 * ULN, "Y", +#' "ALT", AVAL <= 3 * ULN, "N" #' ) #' #' # Deriving MCRIT1MN: ALT < LLN #' definition_mcrit1mn <- exprs( #' ~PARAM, ~condition, ~MCRIT1MN, -#' "ALT", AVAL > ULN, "Y", -#' "ALT", AVAL <= ULN, "N" +#' "ALT", AVAL > ULN, "Y", +#' "ALT", AVAL <= ULN, "N" #' ) #' #' adlb %>% diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 2a7ca9657..bcd3ca307 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -25,16 +25,16 @@ Must contain: e.g. if \code{by_vars} is not specified: -\if{html}{\out{
}}\preformatted{exprs(~condition, ~AVALCAT1, ~AVALCA1N, - AVAL >= 140, ">=140 cm", 1, - AVAL < 140, "<140 cm", 2) +\if{html}{\out{
}}\preformatted{exprs(~condition, ~AVALCAT1, ~AVALCA1N, + AVAL >= 140, ">=140 cm", 1, + AVAL < 140, "<140 cm", 2) }\if{html}{\out{
}} e.g. if \code{by_vars} is specified as \code{exprs(VSTEST)}: -\if{html}{\out{
}}\preformatted{exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL >= 140, ">=140 cm", 1, - "Height", AVAL < 140, "<140 cm", 2) +\if{html}{\out{
}}\preformatted{exprs(~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 140, ">=140 cm", 1, + "Height", AVAL < 140, "<140 cm", 2) }\if{html}{\out{
}}} \item{by_vars}{list of expressions with one element. \code{NULL} by default. @@ -60,10 +60,10 @@ i.e. if and the \code{definition} is: \if{html}{\out{
}}\preformatted{definition <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL > 170, ">170 cm", 1, - "Height", AVAL <= 170, "<=170 cm", 2, - "Height", AVAL <= 160, "<=160 cm", 3 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL > 170, ">170 cm", 1, + "Height", AVAL <= 170, "<=170 cm", 2, + "Height", AVAL <= 160, "<=160 cm", 3 ) }\if{html}{\out{
}} @@ -71,10 +71,10 @@ then \code{AVALCAT1} will be \code{"<=170 cm"}, as this is the first match for \ If you specify: \if{html}{\out{
}}\preformatted{definition <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL <= 160, "<=160 cm", 3, - "Height", AVAL <= 170, "<=170 cm", 2, - "Height", AVAL > 170, ">170 cm", 1 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL <= 160, "<=160 cm", 3, + "Height", AVAL <= 170, "<=170 cm", 2, + "Height", AVAL > 170, ">170 cm", 1 ) }\if{html}{\out{
}} @@ -91,21 +91,21 @@ library(dplyr) library(tibble) advs <- tibble::tribble( - ~USUBJID, ~VSTEST, ~AVAL, + ~USUBJID, ~VSTEST, ~AVAL, "01-701-1015", "Height", 147.32, - "01-701-1015", "Weight", 53.98, + "01-701-1015", "Weight", 53.98, "01-701-1023", "Height", 162.56, - "01-701-1023", "Weight", NA, - "01-701-1028", "Height", NA, - "01-701-1028", "Weight", NA, + "01-701-1023", "Weight", NA, + "01-701-1028", "Height", NA, + "01-701-1028", "Weight", NA, "01-701-1033", "Height", 175.26, - "01-701-1033", "Weight", 88.45 + "01-701-1033", "Weight", 88.45 ) definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, - VSTEST == "Height" & AVAL > 160, ">160 cm", 1, "extra1", - VSTEST == "Height" & AVAL <= 160, "<=160 cm", 2, "extra2" + ~condition, ~AVALCAT1, ~AVALCA1N, ~NEWCOL, + VSTEST == "Height" & AVAL > 160, ">160 cm", 1, "extra1", + VSTEST == "Height" & AVAL <= 160, "<=160 cm", 2, "extra2" ) derive_vars_cat( dataset = advs, @@ -113,11 +113,11 @@ derive_vars_cat( ) # using by_vars: definition2 <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL > 160, ">160 cm", 1, - "Height", AVAL <= 160, "<=160 cm", 2, - "Weight", AVAL > 70, ">70 kg", 1, - "Weight", AVAL <= 70, "<=70 kg", 2 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL > 160, ">160 cm", 1, + "Height", AVAL <= 160, "<=160 cm", 2, + "Weight", AVAL > 70, ">70 kg", 1, + "Weight", AVAL <= 70, "<=70 kg", 2 ) derive_vars_cat( @@ -128,10 +128,10 @@ derive_vars_cat( # With three conditions: definition3 <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL > 170, ">170 cm", 1, - "Height", AVAL <= 170 & AVAL > 160, "<=170 cm", 2, - "Height", AVAL <= 160, "<=160 cm", 3 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL > 170, ">170 cm", 1, + "Height", AVAL <= 170 & AVAL > 160, "<=170 cm", 2, + "Height", AVAL <= 160, "<=160 cm", 3 ) derive_vars_cat( @@ -142,26 +142,26 @@ derive_vars_cat( # Let's derive both the MCRITyML and the MCRITyMN variables adlb <- tibble::tribble( - ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ULN, ~LLN, - "01-701-1015", "ALT", 150, "U/L", 40, 10, - "01-701-1023", "ALT", 70, "U/L", 40, 10, - "01-701-1036", "ALT", 130, "U/L", 40, 10, - "01-701-1048", "ALT", 30, "U/L", 40, 10, - "01-701-1015", "AST", 50, "U/L", 35, 5 + ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ULN, ~LLN, + "01-701-1015", "ALT", 150, "U/L", 40, 10, + "01-701-1023", "ALT", 70, "U/L", 40, 10, + "01-701-1036", "ALT", 130, "U/L", 40, 10, + "01-701-1048", "ALT", 30, "U/L", 40, 10, + "01-701-1015", "AST", 50, "U/L", 35, 5 ) # Deriving MCRIT1ML: ALT > 3x ULN definition_mcrit1ml <- exprs( - ~PARAM, ~condition, ~MCRIT1ML, - "ALT", AVAL > 3 * ULN, "Y", - "ALT", AVAL <= 3 * ULN, "N" + ~PARAM, ~condition, ~MCRIT1ML, + "ALT", AVAL > 3 * ULN, "Y", + "ALT", AVAL <= 3 * ULN, "N" ) # Deriving MCRIT1MN: ALT < LLN definition_mcrit1mn <- exprs( ~PARAM, ~condition, ~MCRIT1MN, - "ALT", AVAL > ULN, "Y", - "ALT", AVAL <= ULN, "N" + "ALT", AVAL > ULN, "Y", + "ALT", AVAL <= ULN, "N" ) adlb \%>\% From 8e727d2372b5dcb0bdaa6b3e00811095106326e0 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 08:56:30 +0000 Subject: [PATCH 43/83] update error message for definition --- R/derive_vars_cat.R | 10 +++++++++- tests/testthat/_snaps/derive_vars_cat.md | 6 +++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 09c0ce3fe..f736658d6 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -193,7 +193,15 @@ derive_vars_cat <- function(dataset, }, error = function(e) { # Catch the error and append your own message - stop("Failed to convert `definition` to tribble: ", e$message) + stop( + paste("Failed to convert `definition` to `tibble`.", + "`definition` should be specified similarly to how you would", + "specify a `tibble` using the `tribble()` function so it", + "can be converted to `tibble` using `tribble()`.", "", + sep = "\n" + ), + e$message + ) } ) assert_data_frame(definition, required_vars = c(exprs(condition), by_vars)) diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index c23963371..efdc4a361 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -184,5 +184,9 @@ # derive_vars_cat Test 12: definition has wrong shape - Failed to convert `definition` to tribble: Data must be rectangular. + Failed to convert `definition` to `tibble`. + `definition` should be specified similarly to how you would + specify a `tibble` using the `tribble()` function so it + can be converted to `tibble` using `tribble()`. + Data must be rectangular. From a3d5751d4ef0c7a5d6b324de474b5f5d1ec349f0 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 09:23:37 +0000 Subject: [PATCH 44/83] Simplify assertions. Update test formatting. --- R/derive_vars_cat.R | 22 +++-- tests/testthat/_snaps/derive_vars_cat.md | 3 +- tests/testthat/test-derive_vars_cat.R | 104 +++++++++++------------ 3 files changed, 64 insertions(+), 65 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index f736658d6..23795a00a 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -171,19 +171,16 @@ derive_vars_cat <- function(dataset, definition, by_vars = NULL) { - assert_data_frame(dataset) assert_expr_list(definition) - if (!is.null(by_vars)) { - assert_vars(by_vars) - assert_data_frame(dataset, - required_vars = c( - admiraldev::extract_vars(definition) %>% unique(), - by_vars - ) + assert_vars(by_vars, optional = TRUE) + assertthat::assert_that(is.null(by_vars) || assertthat::is.scalar(by_vars)) + + assert_data_frame(dataset, + required_vars = c( + admiraldev::extract_vars(definition) %>% unique(), + by_vars ) - } else { - assert_data_frame(dataset, required_vars = admiraldev::extract_vars(definition) %>% unique()) - } + ) # transform definition to tibble names(definition) <- NULL @@ -225,7 +222,8 @@ derive_vars_cat <- function(dataset, # warn if new variables already exist if (any(new_col_names %in% names(dataset))) { warning(paste("Column(s) in `definition` already exist in `dataset`.", - "Did you forget to specify `by_vars`?", + "Did you forget to specify `by_vars`,", + "or are you rerunning your code?", sep = "\n" )) } diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index efdc4a361..8c5fe7ec0 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -59,7 +59,8 @@ # derive_vars_cat Test 2: Forgot to specify by_vars Column(s) in `definition` already exist in `dataset`. - Did you forget to specify `by_vars`? + Did you forget to specify `by_vars`, + or are you rerunning your code? # derive_vars_cat Test 4: Error when definition is not an exprs object diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index 2b34a4b85..4cca9989f 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -1,44 +1,44 @@ # Load the advs dataset advs <- tibble::tribble( - ~USUBJID, ~VSTEST, ~AVAL, + ~USUBJID, ~VSTEST, ~AVAL, "01-701-1015", "Height", 147.32, - "01-701-1015", "Weight", 53.98, + "01-701-1015", "Weight", 53.98, "01-701-1023", "Height", 162.56, - "01-701-1023", "Weight", 78.47, - "01-701-1028", "Height", 177.8, - "01-701-1028", "Weight", 98.88, + "01-701-1023", "Weight", 78.47, + "01-701-1028", "Height", 177.8, + "01-701-1028", "Weight", 98.88, "01-701-1033", "Height", 175.26, - "01-701-1033", "Weight", 88.45, - "01-701-1034", "Height", NA, - "01-701-1034", "Weight", NA, - "01-701-1047", "Height", NA, - "01-701-1047", "Weight", NA, + "01-701-1033", "Weight", 88.45, + "01-701-1034", "Height", NA, + "01-701-1034", "Weight", NA, + "01-701-1047", "Height", NA, + "01-701-1047", "Weight", NA, "01-701-1097", "Height", 168.91, - "01-701-1097", "Weight", 78.02, + "01-701-1097", "Weight", 78.02, "01-701-1111", "Height", 158.24, - "01-701-1111", "Weight", 60.33, + "01-701-1111", "Weight", 60.33, "01-701-1115", "Height", 181.61, - "01-701-1115", "Weight", 78.7, + "01-701-1115", "Weight", 78.7, "01-701-1118", "Height", 180.34, - "01-701-1118", "Weight", 71.67 + "01-701-1118", "Weight", 71.67 ) %>% arrange(VSTEST) ## Test 1: Basic functionality with advs dataset ---- test_that("derive_vars_cat Test 1: Basic functionality with advs dataset", { # Define the condition and categories definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, - VSTEST == "Height" & AVAL >= 160, ">=160", 1, - VSTEST == "Height" & AVAL < 160, "<160", 2 + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL >= 160, ">=160", 1, + VSTEST == "Height" & AVAL < 160, "<160", 2 ) result <- derive_vars_cat(advs, definition) # using by_vars definition2 <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL >= 160, ">=160", 1, - "Height", AVAL < 160, "<160", 2 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160", 2 ) result2 <- derive_vars_cat(advs, definition2, by_vars = exprs(VSTEST)) @@ -51,9 +51,9 @@ test_that("derive_vars_cat Test 1: Basic functionality with advs dataset", { ## Test 2: Forgot to specify by_vars ---- test_that("derive_vars_cat Test 2: Forgot to specify by_vars", { definition <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL >= 160, ">=160", 1, - "Height", AVAL < 160, "<160", 2 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160", 2 ) expect_snapshot_warning(derive_vars_cat(advs, definition)) @@ -63,9 +63,9 @@ test_that("derive_vars_cat Test 2: Forgot to specify by_vars", { test_that("derive_vars_cat Test 3: Error when dataset is not a dataframe", { # Define the condition and categories definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, - VSTEST == "Height" & AVAL >= 160, ">=160", 1, - VSTEST == "Height" & AVAL < 160, "<160", 2 + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL >= 160, ">=160", 1, + VSTEST == "Height" & AVAL < 160, "<160", 2 ) # Snapshot the error message @@ -78,9 +78,9 @@ test_that("derive_vars_cat Test 3: Error when dataset is not a dataframe", { ## Test 4: Error when definition is not an exprs object ---- test_that("derive_vars_cat Test 4: Error when definition is not an exprs object", { definition <- tribble( - ~condition, ~AVALCAT1, ~AVALCA1N, - "AVAL >= 160", ">=160", 1, - "AVAL < 160", "<160", 2 + ~condition, ~AVALCAT1, ~AVALCA1N, + "AVAL >= 160", ">=160", 1, + "AVAL < 160", "<160", 2 ) # Snapshot the error message expect_snapshot_error( @@ -92,9 +92,9 @@ test_that("derive_vars_cat Test 4: Error when definition is not an exprs object" test_that("derive_vars_cat Test 5: Error when required columns are missing from dataset", { # Define the condition and categories (without VSTEST in the dataset) definition <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL >= 160, ">=160", 1, - "Height", AVAL < 160, "<160", 2 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160", 2 ) # Remove VSTEST column from dataset @@ -124,10 +124,10 @@ test_that("derive_vars_cat Test 6: Correct behavior when no conditions are met", test_that("derive_vars_cat Test 7: Overlapping conditions handled correctly", { # Define overlapping conditions definition <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL < 160, "<160", 3, - "Height", AVAL < 170, "<170", 2, - "Height", AVAL >= 170, ">=170", 1 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL < 160, "<160", 3, + "Height", AVAL < 170, "<170", 2, + "Height", AVAL >= 170, ">=170", 1 ) result <- derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)) @@ -141,8 +141,8 @@ test_that("derive_vars_cat Test 8: Error when condition is missing from `definit # Define the condition but omit the 'condition' column from the definition definition <- exprs( ~AVALCAT1, ~AVALCA1N, - ">=160", 1, - "<160", 2 + ">=160", 1, + "<160", 2 ) # Snapshot the error message @@ -156,11 +156,11 @@ test_that("derive_vars_cat Test 8: Error when condition is missing from `definit test_that("derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and Weight)", { # Define conditions for two different VSTEST values: Height and BILI definition <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL >= 160, "Height >= 160", 1, - "Height", AVAL < 160, "Height < 160", 2, - "Weight", AVAL >= 66.68, "Weight >= 66.68", 1, - "Weight", AVAL < 66.68, "Weight < 66.68", 2 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, "Height >= 160", 1, + "Height", AVAL < 160, "Height < 160", 2, + "Weight", AVAL >= 66.68, "Weight >= 66.68", 1, + "Weight", AVAL < 66.68, "Weight < 66.68", 2 ) result <- derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)) @@ -172,9 +172,9 @@ test_that("derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and W test_that("derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset", { # Define conditions and add a third variable (flag) that is TRUE or FALSE definition <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, ~extra_var, - "Height", AVAL >= 160, ">=160", 1, TRUE, - "Height", AVAL < 160, "<160", 2, FALSE + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, ~extra_var, + "Height", AVAL >= 160, ">=160", 1, TRUE, + "Height", AVAL < 160, "<160", 2, FALSE ) result <- derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)) @@ -186,9 +186,9 @@ test_that("derive_vars_cat Test 10: Adding an extra variable (flag) to the datas test_that("derive_vars_cat Test 11: Wrong input for by_vars", { # Define conditions definition <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL >= 160, ">=160", 1, - "Height", AVAL < 160, "<160", 2 + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160", 2 ) expect_error(derive_vars_cat(advs, definition, by_vars = exprs(VSTEST == "Height")), @@ -200,9 +200,9 @@ test_that("derive_vars_cat Test 11: Wrong input for by_vars", { test_that("derive_vars_cat Test 12: definition has wrong shape", { # Define conditions definition_wrong_shape <- exprs( - ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, - "Height", AVAL >= 160, ">=160", 1, - "Height", AVAL < 160, "<160" + ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Height", AVAL >= 160, ">=160", 1, + "Height", AVAL < 160, "<160" ) expect_snapshot_error(derive_vars_cat(advs, definition_wrong_shape, by_vars = exprs(VSTEST))) From 7a912c9a802c9ede37a082f119cb97469cf55200 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 09:56:33 +0000 Subject: [PATCH 45/83] updated example --- R/derive_vars_cat.R | 36 +++++++++++++----------------------- man/derive_vars_cat.Rd | 37 +++++++++++++------------------------ 2 files changed, 26 insertions(+), 47 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 23795a00a..f493510dd 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -137,37 +137,27 @@ #' #' # Let's derive both the MCRITyML and the MCRITyMN variables #' adlb <- tibble::tribble( -#' ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ULN, ~LLN, -#' "01-701-1015", "ALT", 150, "U/L", 40, 10, -#' "01-701-1023", "ALT", 70, "U/L", 40, 10, -#' "01-701-1036", "ALT", 130, "U/L", 40, 10, -#' "01-701-1048", "ALT", 30, "U/L", 40, 10, -#' "01-701-1015", "AST", 50, "U/L", 35, 5 +#' ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ANRHI, +#' "01-701-1015", "ALT", 150, "U/L", 40, +#' "01-701-1023", "ALT", 70, "U/L", 40, +#' "01-701-1036", "ALT", 130, "U/L", 40, +#' "01-701-1048", "ALT", 30, "U/L", 40, +#' "01-701-1015", "AST", 50, "U/L", 35 #' ) #' -#' # Deriving MCRIT1ML: ALT > 3x ULN -#' definition_mcrit1ml <- exprs( -#' ~PARAM, ~condition, ~MCRIT1ML, -#' "ALT", AVAL > 3 * ULN, "Y", -#' "ALT", AVAL <= 3 * ULN, "N" -#' ) -#' -#' # Deriving MCRIT1MN: ALT < LLN -#' definition_mcrit1mn <- exprs( -#' ~PARAM, ~condition, ~MCRIT1MN, -#' "ALT", AVAL > ULN, "Y", -#' "ALT", AVAL <= ULN, "N" +#' definition_mcrit <- exprs( +#' ~PARAM, ~condition, ~MCRIT1ML, ~MCRIT1MN, +#' "ALT", AVAL <= ANRHI, "<=ANRHI", 1, +#' "ALT", ANRHI < AVAL & AVAL <= 3 * ANRHI, ">1-3*ANRHI", 2, +#' "ALT", 3 * ANRHI < AVAL, ">3*ANRHI", 3 #' ) #' #' adlb %>% #' derive_vars_cat( -#' definition = definition_mcrit1ml, +#' definition = definition_mcrit, #' by_vars = exprs(PARAM) #' ) %>% -#' derive_vars_cat( -#' definition = definition_mcrit1mn, -#' by_vars = exprs(PARAM) -#' ) +#' print() derive_vars_cat <- function(dataset, definition, by_vars = NULL) { diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index bcd3ca307..a67e1d8d2 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -142,37 +142,26 @@ derive_vars_cat( # Let's derive both the MCRITyML and the MCRITyMN variables adlb <- tibble::tribble( - ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ULN, ~LLN, - "01-701-1015", "ALT", 150, "U/L", 40, 10, - "01-701-1023", "ALT", 70, "U/L", 40, 10, - "01-701-1036", "ALT", 130, "U/L", 40, 10, - "01-701-1048", "ALT", 30, "U/L", 40, 10, - "01-701-1015", "AST", 50, "U/L", 35, 5 + ~USUBJID, ~PARAM, ~AVAL, ~AVALU, ~ANRHI, + "01-701-1015", "ALT", 150, "U/L", 40, + "01-701-1023", "ALT", 70, "U/L", 40, + "01-701-1036", "ALT", 130, "U/L", 40, + "01-701-1048", "ALT", 30, "U/L", 40, + "01-701-1015", "AST", 50, "U/L", 35 ) -# Deriving MCRIT1ML: ALT > 3x ULN -definition_mcrit1ml <- exprs( - ~PARAM, ~condition, ~MCRIT1ML, - "ALT", AVAL > 3 * ULN, "Y", - "ALT", AVAL <= 3 * ULN, "N" -) - -# Deriving MCRIT1MN: ALT < LLN -definition_mcrit1mn <- exprs( - ~PARAM, ~condition, ~MCRIT1MN, - "ALT", AVAL > ULN, "Y", - "ALT", AVAL <= ULN, "N" +definition_mcrit <- exprs( + ~PARAM, ~condition, ~MCRIT1ML, ~MCRIT1MN, + "ALT", AVAL <= ANRHI, "<=ANRHI", 1, + "ALT", ANRHI < AVAL & AVAL <= 3 * ANRHI, ">1-3*ANRHI", 2, + "ALT", 3 * ANRHI < AVAL, ">3*ANRHI", 3 ) adlb \%>\% derive_vars_cat( - definition = definition_mcrit1ml, - by_vars = exprs(PARAM) - ) \%>\% - derive_vars_cat( - definition = definition_mcrit1mn, + definition = definition_mcrit, by_vars = exprs(PARAM) - ) + ) \%>\% print() } \seealso{ General Derivation Functions for all ADaMs that returns variable appended to dataset: From 69d7ea4431632b05ce9afa32b9882ab75d510ef4 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 10:17:40 +0000 Subject: [PATCH 46/83] add alternative way --- vignettes/adsl.Rmd | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/vignettes/adsl.Rmd b/vignettes/adsl.Rmd index ab693a795..fe1038953 100644 --- a/vignettes/adsl.Rmd +++ b/vignettes/adsl.Rmd @@ -686,18 +686,18 @@ must come after `AGE < 18`. ```{r eval=TRUE} # create lookup tables agegr1_lookup <- exprs( - ~condition, ~AGEGR1, - AGE < 18, "<18", + ~condition, ~AGEGR1, + AGE < 18, "<18", between(AGE, 18, 64), "18-64", - AGE > 64, ">64", - is.na(AGE), "Missing" + AGE > 64, ">64", + is.na(AGE), "Missing" ) region1_lookup <- exprs( - ~condition, ~REGION1, + ~condition, ~REGION1, COUNTRY %in% c("CAN", "USA"), "North America", - !is.na(COUNTRY), "Rest of the World", - is.na(COUNTRY), "Missing" + !is.na(COUNTRY), "Rest of the World", + is.na(COUNTRY), "Missing" ) ``` @@ -710,6 +710,33 @@ adsl <- adsl %>% definition = region1_lookup ) ``` +Alternatively, you can also solve this task with custom functions: +```{r} +#| eval: false +format_agegr1 <- function(var_input) { + case_when( + var_input < 18 ~ "<18", + between(var_input, 18, 64) ~ "18-64", + var_input > 64 ~ ">64", + TRUE ~ "Missing" + ) +} +format_region1 <- function(var_input) { + case_when( + var_input %in% c("CAN", "USA") ~ "North America", + !is.na(var_input) ~ "Rest of the World", + TRUE ~ "Missing" + ) +} + +adsl %>% + mutate( + AGEGR1 = format_agegr1(AGE), + REGION1 = format_region1(COUNTRY) + ) +``` + + ```{r, eval=TRUE, echo=FALSE} dataset_vignette( From 2533193f0e3e135ad9c8f348b05bfe1132622f3d Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 10:19:10 +0000 Subject: [PATCH 47/83] improve wording --- vignettes/adsl.Rmd | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vignettes/adsl.Rmd b/vignettes/adsl.Rmd index fe1038953..e178f0b9d 100644 --- a/vignettes/adsl.Rmd +++ b/vignettes/adsl.Rmd @@ -677,8 +677,11 @@ dataset_vignette( Numeric and categorical variables (`AGE`, `RACE`, `COUNTRY`, etc.) may need to be grouped to perform the required analysis. -`{admiral}` provides the `derive_vars_cat()` function to create such groups. -However, one needs to be careful when considering the order of the conditions in the lookup table. +`{admiral}` provides the `derive_vars_cat()` function to create such groups. +This function is especially useful if more than one variables need to be created for +each condition, which is not the case here. + +Additionally, one needs to be careful when considering the order of the conditions in the lookup table. The category is assigned based on the first match. That means *catch-all* conditions must come after specific conditions, e.g. `!is.na(AGE)` must come after `AGE < 18`. From 98043bf91d96b8df07d2b3930eeecce3af7025e8 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:09:18 +0200 Subject: [PATCH 48/83] Update R/derive_vars_cat.R Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index f493510dd..c8ed7277e 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -1,7 +1,7 @@ #' Derive Categorization Variables Like `AVALCATy` and `AVALCAyN` #' @param dataset #' `r roxygen_param_dataset(expected_vars = c("by_vars", "definition"))` -#' @param definition List of expressions created by: `exprs()`. +#' @param definition List of expressions created by `exprs()`. #' Must be in rectangular format and specified using the same syntax as when creating #' a `tibble` using the `tribble()` function. #' The `definition` object it will be converted to a `tibble` using the `tribble()` function. From ede7f99a6b6ed525112e9a717ed98bf479370a17 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:10:13 +0200 Subject: [PATCH 49/83] Update NEWS.md --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 4ca8e4477..7bb95dc68 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,7 @@ ## New Features - New function `derive_vars_cat()` for deriving pairs of variables or more, e.g. -`AVALCATx` & `AVALCAyN`. (#2480) +`AVALCATx` & `AVALCAxN`. (#2480) - New function `derive_vars_crit_flag()` for deriving criterion flag variables (`CRITy`, `CRITyFL`, `CRITyFLN`). (#2468) From 16b2c38eb1daf19e24190a98b764c1c31a4cbcdc Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:14:33 +0200 Subject: [PATCH 50/83] Update vignettes/generic.Rmd --- vignettes/generic.Rmd | 1 - 1 file changed, 1 deletion(-) diff --git a/vignettes/generic.Rmd b/vignettes/generic.Rmd index 6cfb6bf45..9450dc529 100644 --- a/vignettes/generic.Rmd +++ b/vignettes/generic.Rmd @@ -72,7 +72,6 @@ generic_derivations <- tibble::tribble( "derive_vars_merged()", "selection", "variables", "single", "derive_vars_extreme_event()", "selection", "variables", "multiple", "derive_vars_computed()", "computation", "variables", "single", - "derive_vars_cat()", "selection", "variables", "single", "derive_extreme_event()", "selection", "records", "multiple", "derive_extreme_records()", "selection", "records", "single", "derive_param_computed()", "computation", "records", "single", From 126a17d0295b96a843077559960f002a15cb33c5 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 11:19:02 +0000 Subject: [PATCH 51/83] update man --- man/derive_vars_cat.Rd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index a67e1d8d2..cee2ab448 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -11,7 +11,7 @@ derive_vars_cat(dataset, definition, by_vars = NULL) The variables specified by the \code{by_vars} and \code{definition} arguments are expected to be in the dataset.} -\item{definition}{List of expressions created by: \code{exprs()}. +\item{definition}{List of expressions created by \code{exprs()}. Must be in rectangular format and specified using the same syntax as when creating a \code{tibble} using the \code{tribble()} function. The \code{definition} object it will be converted to a \code{tibble} using the \code{tribble()} function. @@ -161,7 +161,8 @@ adlb \%>\% derive_vars_cat( definition = definition_mcrit, by_vars = exprs(PARAM) - ) \%>\% print() + ) \%>\% + print() } \seealso{ General Derivation Functions for all ADaMs that returns variable appended to dataset: From 930f7f548891a8c5acd7298b6e6de924b02eff55 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 11:37:25 +0000 Subject: [PATCH 52/83] remove reliance on assertthat --- R/derive_vars_cat.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index c8ed7277e..e0444e638 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -163,7 +163,9 @@ derive_vars_cat <- function(dataset, by_vars = NULL) { assert_expr_list(definition) assert_vars(by_vars, optional = TRUE) - assertthat::assert_that(is.null(by_vars) || assertthat::is.scalar(by_vars)) + if(length(by_vars) > 1){ + stop("`by_vars` must contain just one variable, e.g. `exprs(PARAMCD)`") + } assert_data_frame(dataset, required_vars = c( From 9b537db169264c6f2b04ed5de16c56534ef69bfa Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Tue, 24 Sep 2024 11:41:59 +0000 Subject: [PATCH 53/83] styler --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index e0444e638..0e72c0d74 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -163,7 +163,7 @@ derive_vars_cat <- function(dataset, by_vars = NULL) { assert_expr_list(definition) assert_vars(by_vars, optional = TRUE) - if(length(by_vars) > 1){ + if (length(by_vars) > 1) { stop("`by_vars` must contain just one variable, e.g. `exprs(PARAMCD)`") } From e6213a7654545ec7b396fc65dc2a0795df610fff Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Wed, 25 Sep 2024 11:18:15 +0200 Subject: [PATCH 54/83] Update vignettes/bds_finding.Rmd Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- vignettes/bds_finding.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/bds_finding.Rmd b/vignettes/bds_finding.Rmd index f32c9b8ea..b3fe3b2a7 100644 --- a/vignettes/bds_finding.Rmd +++ b/vignettes/bds_finding.Rmd @@ -846,7 +846,7 @@ dataset_vignette( ) ``` -## Derive Categorization Variables (`AVALCATx`) {#cat} +## Derive Categorization Variables (`AVALCATy`) {#cat} We can use the `derive_vars_cat()` function to derive the categorization variables. From a6011db6caf999c2670c91d77750e9ee85997980 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Wed, 25 Sep 2024 11:18:21 +0200 Subject: [PATCH 55/83] Update vignettes/bds_exposure.Rmd Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- vignettes/bds_exposure.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/bds_exposure.Rmd b/vignettes/bds_exposure.Rmd index 65133c7f1..0b4028564 100644 --- a/vignettes/bds_exposure.Rmd +++ b/vignettes/bds_exposure.Rmd @@ -543,7 +543,7 @@ count(adex, PARAMCD, PARAM, PARAMN) Please note, this is an example only and additional columns may be needed for the join depending on your lookup/metadata table. -## Derive Categorization Variables (`AVALCATx`) {#cat} +## Derive Categorization Variables (`AVALCATy`) {#cat} We can use the `derive_vars_cat()` function to derive the categorization variables. From 030e47826193e6b47fff79002fcd27a1b9dd6702 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Wed, 25 Sep 2024 11:19:20 +0200 Subject: [PATCH 56/83] Update vignettes/adsl.Rmd Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- vignettes/adsl.Rmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vignettes/adsl.Rmd b/vignettes/adsl.Rmd index e178f0b9d..8bf7e3e1d 100644 --- a/vignettes/adsl.Rmd +++ b/vignettes/adsl.Rmd @@ -678,8 +678,8 @@ dataset_vignette( Numeric and categorical variables (`AGE`, `RACE`, `COUNTRY`, etc.) may need to be grouped to perform the required analysis. `{admiral}` provides the `derive_vars_cat()` function to create such groups. -This function is especially useful if more than one variables need to be created for -each condition, which is not the case here. +This function is especially useful if more than one variable needs to be created for +each condition, e.g., `AGEGR1` and `AGEGR1N. Additionally, one needs to be careful when considering the order of the conditions in the lookup table. The category is assigned based on the first match. From bef70a4d4274f988709f4439719efa3a53e52a36 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Wed, 25 Sep 2024 11:19:31 +0200 Subject: [PATCH 57/83] Update R/derive_vars_cat.R Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 0e72c0d74..4bad04ada 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -76,7 +76,7 @@ #' In this case, the middle condition should be: #' `AVAL <= 170 & AVAL > 160` #' -#' @return data frame +#' @return The input dataset with the new variables defined in `definition` added #' @family der_gen #' @keywords der_gen #' @export From 2f06d601ae4182468d3a61288009c170e3d03537 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Wed, 25 Sep 2024 11:19:49 +0200 Subject: [PATCH 58/83] Update R/derive_vars_cat.R Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- R/derive_vars_cat.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 4bad04ada..fa9f820c4 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -106,7 +106,8 @@ #' dataset = advs, #' definition = definition #' ) -#' # using by_vars: + +#' # Using by_vars: #' definition2 <- exprs( #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, #' "Height", AVAL > 160, ">160 cm", 1, From e933605e9d1aa9dad5dec38fcd4a129473aba5a6 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Wed, 25 Sep 2024 11:19:56 +0200 Subject: [PATCH 59/83] Update R/derive_vars_cat.R Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- R/derive_vars_cat.R | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index fa9f820c4..be4544cf8 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -157,8 +157,7 @@ #' derive_vars_cat( #' definition = definition_mcrit, #' by_vars = exprs(PARAM) -#' ) %>% -#' print() +#' ) derive_vars_cat <- function(dataset, definition, by_vars = NULL) { From 8b0775b05a904a225ccafc8e8a4cc3725713d051 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 14:07:39 +0000 Subject: [PATCH 60/83] update format --- R/derive_vars_cat.R | 7 ++-- inst/templates/ad_adeg.R | 52 ++++++++++++------------ inst/templates/ad_adpp.R | 52 ++++++++++++------------ inst/templates/ad_advs.R | 34 ++++++++-------- tests/testthat/_snaps/derive_vars_cat.md | 6 +-- 5 files changed, 73 insertions(+), 78 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index be4544cf8..26661f3ce 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -164,7 +164,7 @@ derive_vars_cat <- function(dataset, assert_expr_list(definition) assert_vars(by_vars, optional = TRUE) if (length(by_vars) > 1) { - stop("`by_vars` must contain just one variable, e.g. `exprs(PARAMCD)`") + cli_abort("`by_vars` must contain just one variable, e.g. `exprs(PARAMCD)`") } assert_data_frame(dataset, @@ -182,12 +182,11 @@ derive_vars_cat <- function(dataset, }, error = function(e) { # Catch the error and append your own message - stop( + cli_abort( paste("Failed to convert `definition` to `tibble`.", "`definition` should be specified similarly to how you would", "specify a `tibble` using the `tribble()` function so it", - "can be converted to `tibble` using `tribble()`.", "", - sep = "\n" + "can be converted to `tibble` using `tribble()`." ), e$message ) diff --git a/inst/templates/ad_adeg.R b/inst/templates/ad_adeg.R index 2f6d5158a..fbf9f11cd 100644 --- a/inst/templates/ad_adeg.R +++ b/inst/templates/ad_adeg.R @@ -31,43 +31,43 @@ eg <- convert_blanks_to_na(eg) # Assign PARAMCD, PARAM, and PARAMN param_lookup <- tibble::tribble( - ~EGTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, - "ECGINT", "EGINTP", "ECG Interpretation", 1, - "HR", "HR", "Heart Rate (beats/min)", 2, - "RR", "RR", "RR Duration (msec)", 3, - "RRR", "RRR", "RR Duration Rederived (msec)", 4, - "QT", "QT", "QT Duration (msec)", 10, - "QTCBR", "QTCBR", "QTcB - Bazett's Correction Formula Rederived (msec)", 11, - "QTCFR", "QTCFR", "QTcF - Fridericia's Correction Formula Rederived (msec)", 12, - "QTLCR", "QTLCR", "QTlc - Sagie's Correction Formula Rederived (msec)", 13, + ~EGTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, + "ECGINT", "EGINTP", "ECG Interpretation", 1, + "HR", "HR", "Heart Rate (beats/min)", 2, + "RR", "RR", "RR Duration (msec)", 3, + "RRR", "RRR", "RR Duration Rederived (msec)", 4, + "QT", "QT", "QT Duration (msec)", 10, + "QTCBR", "QTCBR", "QTcB - Bazett's Correction Formula Rederived (msec)", 11, + "QTCFR", "QTCFR", "QTcF - Fridericia's Correction Formula Rederived (msec)", 12, + "QTLCR", "QTLCR", "QTlc - Sagie's Correction Formula Rederived (msec)", 13, ) range_lookup <- tibble::tribble( ~PARAMCD, ~ANRLO, ~ANRHI, - "EGINTP", NA, NA, - "HR", 40, 100, - "RR", 600, 1500, - "QT", 350, 450, - "RRR", 600, 1500, - "QTCBR", 350, 450, - "QTCFR", 350, 450, - "QTLCR", 350, 450, + "EGINTP", NA, NA, + "HR", 40, 100, + "RR", 600, 1500, + "QT", 350, 450, + "RRR", 600, 1500, + "QTCBR", 350, 450, + "QTCFR", 350, 450, + "QTLCR", 350, 450 ) # Assign AVALCAx avalcax_lookup <- exprs( - ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, - "QT", AVAL <= 450, "<= 450 msec", 1, - "QT", AVAL > 450 & AVAL <= 480, ">450<=480 msec", 2, - "QT", AVAL > 480 & AVAL <= 500, ">480<=500 msec", 3, - "QT", AVAL > 500, ">500 msec", 4 + ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, + "QT", AVAL <= 450, "<= 450 msec", 1, + "QT", AVAL > 450 & AVAL <= 480, ">450<=480 msec", 2, + "QT", AVAL > 480 & AVAL <= 500, ">480<=500 msec", 3, + "QT", AVAL > 500, ">500 msec", 4 ) # Assign CHGCAx chgcax_lookup <- exprs( - ~PARAMCD, ~condition, ~CHGCAT1, ~CHGCAT1N, - "QT", CHG <= 30, "<= 30 msec", 1, - "QT", CHG > 30 & CHG <= 60, ">30<=60 msec", 2, - "QT", CHG > 60, ">60 msec", 3 + ~PARAMCD, ~condition, ~CHGCAT1, ~CHGCAT1N, + "QT", CHG <= 30, "<= 30 msec", 1, + "QT", CHG > 30 & CHG <= 60, ">30<=60 msec", 2, + "QT", CHG > 60, ">60 msec", 3 ) # Derivations ---- diff --git a/inst/templates/ad_adpp.R b/inst/templates/ad_adpp.R index 67cf2380a..a95f7e524 100644 --- a/inst/templates/ad_adpp.R +++ b/inst/templates/ad_adpp.R @@ -31,36 +31,36 @@ pp <- convert_blanks_to_na(pp) # Lookup tables ---- param_lookup <- tibble::tribble( - ~PPTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, - "AUCALL", "AUCALL", "AUC All", 1, - "AUCIFO", "AUCIFO", "AUC Infinity Obs", 2, - "AUCIFOD", "AUCIFOD", "AUC Infinity Obs Norm by Dose", 3, - "AUCINT", "AUCINT", "AUC from T1 to T2", 4, - "AUCLST", "AUCLST", "AUC to Last Nonzero Conc", 5, - "AUCPEO", "AUCPEO", "AUC %Extrapolation Obs", 6, - "CEND", "CEND", "Concentration at the end of the infusion", 7, # non Cdisc Term - "CLO", "CLO", "Total CL Obs", 8, - "CLST", "CLST", "Last Nonzero Conc", 9, - "CMAX", "CMAX", "Max Conc", 10, - "CMAXD", "CMAXD", "Max Conc Norm by Dose", 11, - "CSF", "CSF", "CSF to Plasma Ratio", 12, # non Cdisc Term - "LAMZ", "LAMZ", "Lambda z", 13, - "LAMZHL", "LAMZHL", "Half-Life Lambda z", 14, - "LAMZNPT", "LAMZNPT", "Number of Points for Lambda z", 15, - "R2ADJ", "R2ADJ", "R Squared Adjusted", 16, - "TCEND", "TCEND", "Time of CEND", 17, # non Cdisc Term - "TLST", "TLST", "Time of Last Nonzero Conc", 18, - "TMAX", "TMAX", "Time of CMAX", 19, - "VSSO", "VSSO", "Vol Dist Steady State Obs", 20, - "RCAMINT", "RCAMINT", "Ae", 21, - "RENALCL", "RENALCL", "CLR", 22 + ~PPTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, + "AUCALL", "AUCALL", "AUC All", 1, + "AUCIFO", "AUCIFO", "AUC Infinity Obs", 2, + "AUCIFOD", "AUCIFOD", "AUC Infinity Obs Norm by Dose", 3, + "AUCINT", "AUCINT", "AUC from T1 to T2", 4, + "AUCLST", "AUCLST", "AUC to Last Nonzero Conc", 5, + "AUCPEO", "AUCPEO", "AUC %Extrapolation Obs", 6, + "CEND", "CEND", "Concentration at the end of the infusion", 7, # non Cdisc Term + "CLO", "CLO", "Total CL Obs", 8, + "CLST", "CLST", "Last Nonzero Conc", 9, + "CMAX", "CMAX", "Max Conc", 10, + "CMAXD", "CMAXD", "Max Conc Norm by Dose", 11, + "CSF", "CSF", "CSF to Plasma Ratio", 12, # non Cdisc Term + "LAMZ", "LAMZ", "Lambda z", 13, + "LAMZHL", "LAMZHL", "Half-Life Lambda z", 14, + "LAMZNPT", "LAMZNPT", "Number of Points for Lambda z", 15, + "R2ADJ", "R2ADJ", "R Squared Adjusted", 16, + "TCEND", "TCEND", "Time of CEND", 17, # non Cdisc Term + "TLST", "TLST", "Time of Last Nonzero Conc", 18, + "TMAX", "TMAX", "Time of CMAX", 19, + "VSSO", "VSSO", "Vol Dist Steady State Obs", 20, + "RCAMINT", "RCAMINT", "Ae", 21, + "RENALCL", "RENALCL", "CLR", 22 ) # Assign AVALCATx avalcax_lookup <- exprs( - ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, - "AUCALL", AVAL < 19, "<19", 1, - "AUCALL", AVAL >= 19, ">=19", 2 + ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, + "AUCALL", AVAL < 19, "<19", 1, + "AUCALL", AVAL >= 19, ">=19", 2 ) attr(param_lookup$PPTESTCD, "label") <- "Parameter Short Name" diff --git a/inst/templates/ad_advs.R b/inst/templates/ad_advs.R index 3b50dec8f..5a6151ee1 100644 --- a/inst/templates/ad_advs.R +++ b/inst/templates/ad_advs.R @@ -29,16 +29,16 @@ vs <- convert_blanks_to_na(vs) # Assign PARAMCD, PARAM, and PARAMN param_lookup <- tibble::tribble( - ~VSTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, - "SYSBP", "SYSBP", "Systolic Blood Pressure (mmHg)", 1, - "DIABP", "DIABP", "Diastolic Blood Pressure (mmHg)", 2, - "PULSE", "PULSE", "Pulse Rate (beats/min)", 3, - "WEIGHT", "WEIGHT", "Weight (kg)", 4, - "HEIGHT", "HEIGHT", "Height (cm)", 5, - "TEMP", "TEMP", "Temperature (C)", 6, - "MAP", "MAP", "Mean Arterial Pressure (mmHg)", 7, - "BMI", "BMI", "Body Mass Index(kg/m^2)", 8, - "BSA", "BSA", "Body Surface Area(m^2)", 9 + ~VSTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, + "SYSBP", "SYSBP", "Systolic Blood Pressure (mmHg)", 1, + "DIABP", "DIABP", "Diastolic Blood Pressure (mmHg)", 2, + "PULSE", "PULSE", "Pulse Rate (beats/min)", 3, + "WEIGHT", "WEIGHT", "Weight (kg)", 4, + "HEIGHT", "HEIGHT", "Height (cm)", 5, + "TEMP", "TEMP", "Temperature (C)", 6, + "MAP", "MAP", "Mean Arterial Pressure (mmHg)", 7, + "BMI", "BMI", "Body Mass Index(kg/m^2)", 8, + "BSA", "BSA", "Body Surface Area(m^2)", 9 ) attr(param_lookup$VSTESTCD, "label") <- "Vital Signs Test Short Name" @@ -46,17 +46,17 @@ attr(param_lookup$VSTESTCD, "label") <- "Vital Signs Test Short Name" # Assign ANRLO/HI, A1LO/HI range_lookup <- tibble::tribble( ~PARAMCD, ~ANRLO, ~ANRHI, ~A1LO, ~A1HI, - "SYSBP", 90, 130, 70, 140, - "DIABP", 60, 80, 40, 90, - "PULSE", 60, 100, 40, 110, - "TEMP", 36.5, 37.5, 35, 38 + "SYSBP", 90, 130, 70, 140, + "DIABP", 60, 80, 40, 90, + "PULSE", 60, 100, 40, 110, + "TEMP", 36.5, 37.5, 35, 38 ) # Assign AVALCATx avalcax_lookup <- exprs( - ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, - "HEIGHT", AVAL > 100, ">100 cm", 1, - "HEIGHT", AVAL <= 100, "<=100 cm", 2 + ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, + "HEIGHT", AVAL > 100, ">100 cm", 1, + "HEIGHT", AVAL <= 100, "<=100 cm", 2 ) # Derivations ---- diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index 8c5fe7ec0..362a5f75d 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -185,9 +185,5 @@ # derive_vars_cat Test 12: definition has wrong shape - Failed to convert `definition` to `tibble`. - `definition` should be specified similarly to how you would - specify a `tibble` using the `tribble()` function so it - can be converted to `tibble` using `tribble()`. - Data must be rectangular. + Failed to convert `definition` to `tibble`. `definition` should be specified similarly to how you would specify a `tibble` using the `tribble()` function so it can be converted to `tibble` using `tribble()`. From 381ec725794725e45dcd799ec4b235d58c414ba2 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 14:20:39 +0000 Subject: [PATCH 61/83] update format --- inst/templates/ad_adlb.R | 134 +++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/inst/templates/ad_adlb.R b/inst/templates/ad_adlb.R index b04807ec8..d6ad0f5ec 100644 --- a/inst/templates/ad_adlb.R +++ b/inst/templates/ad_adlb.R @@ -29,54 +29,54 @@ lb <- convert_blanks_to_na(lb) # 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, - "ALT", "ALT", "Alanine Aminotransferase (U/L)", 3, - "ANISO", "ANISO", "Anisocytes", 4, - "AST", "AST", "Aspartate Aminotransferase (U/L)", 5, - "BASO", "BASO", "Basophils Abs (10^9/L)", 6, - "BASOLE", "BASOLE", "Basophils/Leukocytes (FRACTION)", 7, - "BILI", "BILI", "Bilirubin (umol/L)", 8, - "BUN", "BUN", "Blood Urea Nitrogen (mmol/L)", 9, - "CA", "CA", "Calcium (mmol/L)", 10, - "CHOL", "CHOLES", "Cholesterol (mmol/L)", 11, - "CK", "CK", "Creatinine Kinase (U/L)", 12, - "CL", "CL", "Chloride (mmol/L)", 13, - "COLOR", "COLOR", "Color", 14, - "CREAT", "CREAT", "Creatinine (umol/L)", 15, - "EOS", "EOS", "Eosinophils (10^9/L)", 16, - "EOSLE", "EOSLE", "Eosinophils/Leukocytes (FRACTION)", 17, - "GGT", "GGT", "Gamma Glutamyl Transferase (U/L)", 18, - "GLUC", "GLUC", "Glucose (mmol/L)", 19, - "HBA1C", "HBA1C", "Hemoglobin A1C (1)", 20, - "HCT", "HCT", "Hematocrit (1)", 21, - "HGB", "HGB", "Hemoglobin (mmol/L)", 22, - "K", "POTAS", "Potassium (mmol/L)", 23, - "KETONES", "KETON", "Ketones", 24, - "LYM", "LYMPH", "Lymphocytes Abs (10^9/L)", 25, - "LYMLE", "LYMPHLE", "Lymphocytes/Leukocytes (FRACTION)", 26, - "MACROCY", "MACROC", "Macrocytes", 27, - "MCH", "MCH", "Ery. Mean Corpuscular Hemoglobin (fmol(Fe))", 28, - "MCHC", "MCHC", "Ery. Mean Corpuscular HGB Concentration (mmol/L)", 29, - "MCV", "MCV", "Ery. Mean Corpuscular Volume (f/L)", 30, - "MICROCY", "MICROC", "Microcytes", 31, - "MONO", "MONO", "Monocytes (10^9/L)", 32, - "MONOLE", "MONOLE", "Monocytes/Leukocytes (FRACTION)", 33, - "PH", "PH", "pH", 34, - "PHOS", "PHOS", "Phosphate (mmol/L)", 35, - "PLAT", "PLAT", "Platelet (10^9/L)", 36, - "POIKILO", "POIKIL", "Poikilocytes", 37, - "POLYCHR", "POLYCH", "Polychromasia", 38, - "PROT", "PROT", "Protein (g/L)", 39, - "RBC", "RBC", "Erythrocytes (TI/L)", 40, - "SODIUM", "SODIUM", "Sodium (mmol/L)", 41, - "SPGRAV", "SPGRAV", "Specific Gravity", 42, - "TSH", "TSH", "Thyrotropin (mU/L)", 43, - "URATE", "URATE", "Urate (umol/L)", 44, - "UROBIL", "UROBIL", "Urobilinogen", 45, - "VITB12", "VITB12", "Vitamin B12 (pmol/L)", 46, - "WBC", "WBC", "Leukocytes (10^9/L)", 47 + ~LBTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, + "ALB", "ALB", "Albumin (g/L)", 1, + "ALP", "ALKPH", "Alkaline Phosphatase (U/L)", 2, + "ALT", "ALT", "Alanine Aminotransferase (U/L)", 3, + "ANISO", "ANISO", "Anisocytes", 4, + "AST", "AST", "Aspartate Aminotransferase (U/L)", 5, + "BASO", "BASO", "Basophils Abs (10^9/L)", 6, + "BASOLE", "BASOLE", "Basophils/Leukocytes (FRACTION)", 7, + "BILI", "BILI", "Bilirubin (umol/L)", 8, + "BUN", "BUN", "Blood Urea Nitrogen (mmol/L)", 9, + "CA", "CA", "Calcium (mmol/L)", 10, + "CHOL", "CHOLES", "Cholesterol (mmol/L)", 11, + "CK", "CK", "Creatinine Kinase (U/L)", 12, + "CL", "CL", "Chloride (mmol/L)", 13, + "COLOR", "COLOR", "Color", 14, + "CREAT", "CREAT", "Creatinine (umol/L)", 15, + "EOS", "EOS", "Eosinophils (10^9/L)", 16, + "EOSLE", "EOSLE", "Eosinophils/Leukocytes (FRACTION)", 17, + "GGT", "GGT", "Gamma Glutamyl Transferase (U/L)", 18, + "GLUC", "GLUC", "Glucose (mmol/L)", 19, + "HBA1C", "HBA1C", "Hemoglobin A1C (1)", 20, + "HCT", "HCT", "Hematocrit (1)", 21, + "HGB", "HGB", "Hemoglobin (mmol/L)", 22, + "K", "POTAS", "Potassium (mmol/L)", 23, + "KETONES", "KETON", "Ketones", 24, + "LYM", "LYMPH", "Lymphocytes Abs (10^9/L)", 25, + "LYMLE", "LYMPHLE", "Lymphocytes/Leukocytes (FRACTION)", 26, + "MACROCY", "MACROC", "Macrocytes", 27, + "MCH", "MCH", "Ery. Mean Corpuscular Hemoglobin (fmol(Fe))", 28, + "MCHC", "MCHC", "Ery. Mean Corpuscular HGB Concentration (mmol/L)", 29, + "MCV", "MCV", "Ery. Mean Corpuscular Volume (f/L)", 30, + "MICROCY", "MICROC", "Microcytes", 31, + "MONO", "MONO", "Monocytes (10^9/L)", 32, + "MONOLE", "MONOLE", "Monocytes/Leukocytes (FRACTION)", 33, + "PH", "PH", "pH", 34, + "PHOS", "PHOS", "Phosphate (mmol/L)", 35, + "PLAT", "PLAT", "Platelet (10^9/L)", 36, + "POIKILO", "POIKIL", "Poikilocytes", 37, + "POLYCHR", "POLYCH", "Polychromasia", 38, + "PROT", "PROT", "Protein (g/L)", 39, + "RBC", "RBC", "Erythrocytes (TI/L)", 40, + "SODIUM", "SODIUM", "Sodium (mmol/L)", 41, + "SPGRAV", "SPGRAV", "Specific Gravity", 42, + "TSH", "TSH", "Thyrotropin (mU/L)", 43, + "URATE", "URATE", "Urate (umol/L)", 44, + "UROBIL", "UROBIL", "Urobilinogen", 45, + "VITB12", "VITB12", "Vitamin B12 (pmol/L)", 46, + "WBC", "WBC", "Leukocytes (10^9/L)", 47 ) @@ -241,25 +241,25 @@ adlb <- adlb %>% # ATOXDSCL and ATOXDSCH hold terms defined by NCI-CTCAEv4. # See (https://pharmaverse.github.io/admiral/articles/lab_grading.html#implement_ctcv4) grade_lookup <- tibble::tribble( - ~PARAMCD, ~ATOXDSCL, ~ATOXDSCH, - "ALB", "Hypoalbuminemia", NA_character_, - "ALKPH", NA_character_, "Alkaline phosphatase increased", - "ALT", NA_character_, "Alanine aminotransferase increased", - "AST", NA_character_, "Aspartate aminotransferase increased", - "BILI", NA_character_, "Blood bilirubin increased", - "CA", "Hypocalcemia", "Hypercalcemia", - "CHOLES", NA_character_, "Cholesterol high", - "CK", NA_character_, "CPK increased", - "CREAT", NA_character_, "Creatinine increased", - "GGT", NA_character_, "GGT increased", - "GLUC", "Hypoglycemia", "Hyperglycemia", - "HGB", "Anemia", "Hemoglobin increased", - "POTAS", "Hypokalemia", "Hyperkalemia", - "LYMPH", "CD4 lymphocytes decreased", NA_character_, - "PHOS", "Hypophosphatemia", NA_character_, - "PLAT", "Platelet count decreased", NA_character_, - "SODIUM", "Hyponatremia", "Hypernatremia", - "WBC", "White blood cell decreased", "Leukocytosis", + ~PARAMCD, ~ATOXDSCL, ~ATOXDSCH, + "ALB", "Hypoalbuminemia", NA_character_, + "ALKPH", NA_character_, "Alkaline phosphatase increased", + "ALT", NA_character_, "Alanine aminotransferase increased", + "AST", NA_character_, "Aspartate aminotransferase increased", + "BILI", NA_character_, "Blood bilirubin increased", + "CA", "Hypocalcemia", "Hypercalcemia", + "CHOLES", NA_character_, "Cholesterol high", + "CK", NA_character_, "CPK increased", + "CREAT", NA_character_, "Creatinine increased", + "GGT", NA_character_, "GGT increased", + "GLUC", "Hypoglycemia", "Hyperglycemia", + "HGB", "Anemia", "Hemoglobin increased", + "POTAS", "Hypokalemia", "Hyperkalemia", + "LYMPH", "CD4 lymphocytes decreased", NA_character_, + "PHOS", "Hypophosphatemia", NA_character_, + "PLAT", "Platelet count decreased", NA_character_, + "SODIUM", "Hyponatremia", "Hypernatremia", + "WBC", "White blood cell decreased", "Leukocytosis", ) # Assign grade criteria From dfc528973c14da2b44af3343952e62a035d45fc7 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 14:24:55 +0000 Subject: [PATCH 62/83] format --- inst/templates/ad_adex.R | 58 ++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/inst/templates/ad_adex.R b/inst/templates/ad_adex.R index 96031758c..ac0f980ca 100644 --- a/inst/templates/ad_adex.R +++ b/inst/templates/ad_adex.R @@ -257,41 +257,41 @@ adex <- adex %>% # Assign PARAMCD, PARAM, and PARAMN # ---- Lookup tables ---- param_lookup <- tibble::tribble( - ~PARAMCD, ~PARAM, ~PARAMN, - "DURD", "Study drug duration during constant dosing interval (days)", 1, - "DOSE", "Dose administered during constant dosing interval (mg)", 2, - "PLDOSE", "Planned dose during constant dosing interval (mg)", 3, - "ADJ", "Dose adjusted during constant dosing interval", 4, - "ADJAE", "Dose adjusted due to AE during constant dosing interval", 5, - "TDURD", "Overall duration (days)", 7, - "TDOSE", "Total dose administered (mg)", 8, - "AVDDSE", "Average daily dose administered (mg/mg)", 10, - "TPDOSE", "Total planned dose (mg)", 11, - "TADJ", "Dose adjusted during study", 13, - "TADJAE", "Dose adjusted during study due to AE", 14, - "PDURD", "Overall duration in W2-W24 (days)", 19, - "PDOSE", "Total dose administered in W2-W2 (mg)4", 20, - "PPDOSE", "Total planned dose in W2-W24 (mg)", 21, - "PAVDDSE", "Average daily dose administered in W2-W24 (mg)", 23, - "PADJ", "Dose adjusted during W2-W24", 24, - "PADJAE", "Dose adjusted in W2-W24 due to AE", 25, - "TDOSINT", "Overall dose intensity (%)", 90, - "PDOSINT", "W2-24 dose intensity (%)", 91 + ~PARAMCD, ~PARAM, ~PARAMN, + "DURD", "Study drug duration during constant dosing interval (days)", 1, + "DOSE", "Dose administered during constant dosing interval (mg)", 2, + "PLDOSE", "Planned dose during constant dosing interval (mg)", 3, + "ADJ", "Dose adjusted during constant dosing interval", 4, + "ADJAE", "Dose adjusted due to AE during constant dosing interval", 5, + "TDURD", "Overall duration (days)", 7, + "TDOSE", "Total dose administered (mg)", 8, + "AVDDSE", "Average daily dose administered (mg/mg)", 10, + "TPDOSE", "Total planned dose (mg)", 11, + "TADJ", "Dose adjusted during study", 13, + "TADJAE", "Dose adjusted during study due to AE", 14, + "PDURD", "Overall duration in W2-W24 (days)", 19, + "PDOSE", "Total dose administered in W2-W2 (mg)4", 20, + "PPDOSE", "Total planned dose in W2-W24 (mg)", 21, + "PAVDDSE", "Average daily dose administered in W2-W24 (mg)", 23, + "PADJ", "Dose adjusted during W2-W24", 24, + "PADJAE", "Dose adjusted in W2-W24 due to AE", 25, + "TDOSINT", "Overall dose intensity (%)", 90, + "PDOSINT", "W2-24 dose intensity (%)", 91 ) # Assign AVALCATx avalcax_lookup <- exprs( - ~PARAMCD, ~condition, ~AVALCAT1, - "TDURD", AVAL >= 90, ">= 90 days", + ~PARAMCD, ~condition, ~AVALCAT1, + "TDURD", AVAL >= 90, ">= 90 days", "TDURD", AVAL >= 30 & AVAL < 90, ">= 30 and < 90 days", - "TDURD", AVAL < 30, "< 30 days", - "PDURD", AVAL >= 90, ">= 90 days", + "TDURD", AVAL < 30, "< 30 days", + "PDURD", AVAL >= 90, ">= 90 days", "PDURD", AVAL >= 30 & AVAL < 90, ">= 30 and < 90 days", - "PDURD", AVAL < 30, "< 30 days", - "TDOSE", AVAL < 100, "< 100 mg", - "TDOSE", AVAL >= 100, ">= 100 mg", - "PDOSE", AVAL < 100, "< 100 mg", - "PDOSE", AVAL >= 100, ">= 100 mg" + "PDURD", AVAL < 30, "< 30 days", + "TDOSE", AVAL < 100, "< 100 mg", + "TDOSE", AVAL >= 100, ">= 100 mg", + "PDOSE", AVAL < 100, "< 100 mg", + "PDOSE", AVAL >= 100, ">= 100 mg" ) adex <- adex %>% From 089e90aa642a2964e1d61df4778eab455d75e917 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:29:08 +0200 Subject: [PATCH 63/83] Update R/derive_vars_cat.R --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 26661f3ce..187f3e058 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -247,7 +247,7 @@ derive_vars_cat <- function(dataset, #' @examples #' # Extend an existing condition to include a check for 'AGE == "30"' #' extend_condition("SEX == 'M'", "AGE", "30") -#' @noRd +#' @keywords internal extend_condition <- function(cond, var, is) { paste(cond, " & ", var, " == '", is, "'", sep = "") } From eac433fb5c7ce149bbeda9ee9b599f28d5dc857a Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 14:40:57 +0000 Subject: [PATCH 64/83] style & spelling --- R/derive_vars_cat.R | 3 ++- vignettes/adsl.Rmd | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 187f3e058..96f190eaf 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -183,7 +183,8 @@ derive_vars_cat <- function(dataset, error = function(e) { # Catch the error and append your own message cli_abort( - paste("Failed to convert `definition` to `tibble`.", + paste( + "Failed to convert `definition` to `tibble`.", "`definition` should be specified similarly to how you would", "specify a `tibble` using the `tribble()` function so it", "can be converted to `tibble` using `tribble()`." diff --git a/vignettes/adsl.Rmd b/vignettes/adsl.Rmd index 8bf7e3e1d..f62060776 100644 --- a/vignettes/adsl.Rmd +++ b/vignettes/adsl.Rmd @@ -679,7 +679,7 @@ Numeric and categorical variables (`AGE`, `RACE`, `COUNTRY`, etc.) may need to b the required analysis. `{admiral}` provides the `derive_vars_cat()` function to create such groups. This function is especially useful if more than one variable needs to be created for -each condition, e.g., `AGEGR1` and `AGEGR1N. +each condition, e.g., `AGEGR1` and `AGEGR1N`. Additionally, one needs to be careful when considering the order of the conditions in the lookup table. The category is assigned based on the first match. From e98c228d40e8b94b3c605f6a13e04eeff2941d4e Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 15:03:05 +0000 Subject: [PATCH 65/83] update tests to tibbles --- tests/testthat/_snaps/derive_vars_cat.md | 180 +------------------ tests/testthat/test-derive_vars_cat.R | 211 ++++++++++++++++++----- 2 files changed, 173 insertions(+), 218 deletions(-) diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index 362a5f75d..372243c03 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -1,189 +1,15 @@ -# derive_vars_cat Test 1: Basic functionality with advs dataset - - Code - result - Output - # A tibble: 20 x 5 - USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - - 1 01-701-1015 Height 147. <160 2 - 2 01-701-1023 Height 163. >=160 1 - 3 01-701-1028 Height 178. >=160 1 - 4 01-701-1033 Height 175. >=160 1 - 5 01-701-1034 Height NA NA - 6 01-701-1047 Height NA NA - 7 01-701-1097 Height 169. >=160 1 - 8 01-701-1111 Height 158. <160 2 - 9 01-701-1115 Height 182. >=160 1 - 10 01-701-1118 Height 180. >=160 1 - 11 01-701-1015 Weight 54.0 NA - 12 01-701-1023 Weight 78.5 NA - 13 01-701-1028 Weight 98.9 NA - 14 01-701-1033 Weight 88.4 NA - 15 01-701-1034 Weight NA NA - 16 01-701-1047 Weight NA NA - 17 01-701-1097 Weight 78.0 NA - 18 01-701-1111 Weight 60.3 NA - 19 01-701-1115 Weight 78.7 NA - 20 01-701-1118 Weight 71.7 NA - ---- - - Code - result2 - Output - # A tibble: 20 x 5 - USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - - 1 01-701-1015 Height 147. <160 2 - 2 01-701-1023 Height 163. >=160 1 - 3 01-701-1028 Height 178. >=160 1 - 4 01-701-1033 Height 175. >=160 1 - 5 01-701-1034 Height NA NA - 6 01-701-1047 Height NA NA - 7 01-701-1097 Height 169. >=160 1 - 8 01-701-1111 Height 158. <160 2 - 9 01-701-1115 Height 182. >=160 1 - 10 01-701-1118 Height 180. >=160 1 - 11 01-701-1015 Weight 54.0 NA - 12 01-701-1023 Weight 78.5 NA - 13 01-701-1028 Weight 98.9 NA - 14 01-701-1033 Weight 88.4 NA - 15 01-701-1034 Weight NA NA - 16 01-701-1047 Weight NA NA - 17 01-701-1097 Weight 78.0 NA - 18 01-701-1111 Weight 60.3 NA - 19 01-701-1115 Weight 78.7 NA - 20 01-701-1118 Weight 71.7 NA - -# derive_vars_cat Test 2: Forgot to specify by_vars +# derive_vars_cat Test 3: Forgot to specify by_vars Column(s) in `definition` already exist in `dataset`. Did you forget to specify `by_vars`, or are you rerunning your code? -# derive_vars_cat Test 4: Error when definition is not an exprs object +# derive_vars_cat Test 5: Error when definition is not an exprs object Argument `definition` must be a list of expressions but is a tibble. i To create a list of expressions use `exprs()`. -# derive_vars_cat Test 6: Correct behavior when no conditions are met - - Code - result - Output - # A tibble: 20 x 5 - USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - - 1 01-701-1015 Height 147. NA - 2 01-701-1023 Height 163. NA - 3 01-701-1028 Height 178. NA - 4 01-701-1033 Height 175. NA - 5 01-701-1034 Height NA NA - 6 01-701-1047 Height NA NA - 7 01-701-1097 Height 169. NA - 8 01-701-1111 Height 158. NA - 9 01-701-1115 Height 182. NA - 10 01-701-1118 Height 180. NA - 11 01-701-1015 Weight 54.0 NA - 12 01-701-1023 Weight 78.5 NA - 13 01-701-1028 Weight 98.9 NA - 14 01-701-1033 Weight 88.4 NA - 15 01-701-1034 Weight NA NA - 16 01-701-1047 Weight NA NA - 17 01-701-1097 Weight 78.0 NA - 18 01-701-1111 Weight 60.3 NA - 19 01-701-1115 Weight 78.7 NA - 20 01-701-1118 Weight 71.7 NA - -# derive_vars_cat Test 7: Overlapping conditions handled correctly - - Code - result - Output - # A tibble: 20 x 5 - USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - - 1 01-701-1015 Height 147. <160 3 - 2 01-701-1023 Height 163. <170 2 - 3 01-701-1028 Height 178. >=170 1 - 4 01-701-1033 Height 175. >=170 1 - 5 01-701-1034 Height NA NA - 6 01-701-1047 Height NA NA - 7 01-701-1097 Height 169. <170 2 - 8 01-701-1111 Height 158. <160 3 - 9 01-701-1115 Height 182. >=170 1 - 10 01-701-1118 Height 180. >=170 1 - 11 01-701-1015 Weight 54.0 NA - 12 01-701-1023 Weight 78.5 NA - 13 01-701-1028 Weight 98.9 NA - 14 01-701-1033 Weight 88.4 NA - 15 01-701-1034 Weight NA NA - 16 01-701-1047 Weight NA NA - 17 01-701-1097 Weight 78.0 NA - 18 01-701-1111 Weight 60.3 NA - 19 01-701-1115 Weight 78.7 NA - 20 01-701-1118 Weight 71.7 NA - -# derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and Weight) - - Code - result - Output - # A tibble: 20 x 5 - USUBJID VSTEST AVAL AVALCAT1 AVALCA1N - - 1 01-701-1015 Height 147. Height < 160 2 - 2 01-701-1023 Height 163. Height >= 160 1 - 3 01-701-1028 Height 178. Height >= 160 1 - 4 01-701-1033 Height 175. Height >= 160 1 - 5 01-701-1034 Height NA NA - 6 01-701-1047 Height NA NA - 7 01-701-1097 Height 169. Height >= 160 1 - 8 01-701-1111 Height 158. Height < 160 2 - 9 01-701-1115 Height 182. Height >= 160 1 - 10 01-701-1118 Height 180. Height >= 160 1 - 11 01-701-1015 Weight 54.0 Weight < 66.68 2 - 12 01-701-1023 Weight 78.5 Weight >= 66.68 1 - 13 01-701-1028 Weight 98.9 Weight >= 66.68 1 - 14 01-701-1033 Weight 88.4 Weight >= 66.68 1 - 15 01-701-1034 Weight NA NA - 16 01-701-1047 Weight NA NA - 17 01-701-1097 Weight 78.0 Weight >= 66.68 1 - 18 01-701-1111 Weight 60.3 Weight < 66.68 2 - 19 01-701-1115 Weight 78.7 Weight >= 66.68 1 - 20 01-701-1118 Weight 71.7 Weight >= 66.68 1 - -# derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset - - Code - result - Output - # A tibble: 20 x 6 - USUBJID VSTEST AVAL AVALCAT1 AVALCA1N extra_var - - 1 01-701-1015 Height 147. <160 2 FALSE - 2 01-701-1023 Height 163. >=160 1 TRUE - 3 01-701-1028 Height 178. >=160 1 TRUE - 4 01-701-1033 Height 175. >=160 1 TRUE - 5 01-701-1034 Height NA NA NA - 6 01-701-1047 Height NA NA NA - 7 01-701-1097 Height 169. >=160 1 TRUE - 8 01-701-1111 Height 158. <160 2 FALSE - 9 01-701-1115 Height 182. >=160 1 TRUE - 10 01-701-1118 Height 180. >=160 1 TRUE - 11 01-701-1015 Weight 54.0 NA NA - 12 01-701-1023 Weight 78.5 NA NA - 13 01-701-1028 Weight 98.9 NA NA - 14 01-701-1033 Weight 88.4 NA NA - 15 01-701-1034 Weight NA NA NA - 16 01-701-1047 Weight NA NA NA - 17 01-701-1097 Weight 78.0 NA NA - 18 01-701-1111 Weight 60.3 NA NA - 19 01-701-1115 Weight 78.7 NA NA - 20 01-701-1118 Weight 71.7 NA NA - -# derive_vars_cat Test 12: definition has wrong shape +# derive_vars_cat Test 13: definition has wrong shape Failed to convert `definition` to `tibble`. `definition` should be specified similarly to how you would specify a `tibble` using the `tribble()` function so it can be converted to `tibble` using `tribble()`. diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index 4cca9989f..42b70fa82 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -23,8 +23,31 @@ advs <- tibble::tribble( "01-701-1118", "Weight", 71.67 ) %>% arrange(VSTEST) -## Test 1: Basic functionality with advs dataset ---- -test_that("derive_vars_cat Test 1: Basic functionality with advs dataset", { +expected_result <- tibble::tribble( + ~USUBJID, ~VSTEST, ~AVAL, ~AVALCAT1, ~AVALCA1N, + "01-701-1015", "Height", 147.32, "<160", 2, + "01-701-1023", "Height", 162.56, ">=160", 1, + "01-701-1028", "Height", 177.8, ">=160", 1, + "01-701-1033", "Height", 175.26, ">=160", 1, + "01-701-1034", "Height", NA, NA, NA, + "01-701-1047", "Height", NA, NA, NA, + "01-701-1097", "Height", 168.91, ">=160", 1, + "01-701-1111", "Height", 158.24, "<160", 2, + "01-701-1115", "Height", 181.61, ">=160", 1, + "01-701-1118", "Height", 180.34, ">=160", 1, + "01-701-1015", "Weight", 53.98, NA, NA, + "01-701-1023", "Weight", 78.47, NA, NA, + "01-701-1028", "Weight", 98.88, NA, NA, + "01-701-1033", "Weight", 88.45, NA, NA, + "01-701-1034", "Weight", NA, NA, NA, + "01-701-1047", "Weight", NA, NA, NA, + "01-701-1097", "Weight", 78.02, NA, NA, + "01-701-1111", "Weight", 60.33, NA, NA, + "01-701-1115", "Weight", 78.7, NA, NA, + "01-701-1118", "Weight", 71.67, NA, NA +) +## Test 1: Basic functionality without by_vars ---- +test_that("derive_vars_cat Test 1: Basic functionality without by_vars", { # Define the condition and categories definition <- exprs( ~condition, ~AVALCAT1, ~AVALCA1N, @@ -32,24 +55,36 @@ test_that("derive_vars_cat Test 1: Basic functionality with advs dataset", { VSTEST == "Height" & AVAL < 160, "<160", 2 ) - result <- derive_vars_cat(advs, definition) + expect_dfs_equal(base = + derive_vars_cat( + advs, + definition), + compare = expected_result, + keys = c("USUBJID", "VSTEST")) +}) - # using by_vars - definition2 <- exprs( +## Test 2: Basic functionality with by_vars ---- +test_that("derive_vars_cat Test 2: Basic functionality with by_vars", { + # Define the condition and categories + definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, "Height", AVAL >= 160, ">=160", 1, "Height", AVAL < 160, "<160", 2 ) - result2 <- derive_vars_cat(advs, definition2, by_vars = exprs(VSTEST)) - expect_snapshot(result) - expect_snapshot(result2) - expect_dfs_equal(base = result, compare = result2, keys = c("USUBJID", "VSTEST")) + + expect_dfs_equal(base = + derive_vars_cat( + advs, + definition, + by_vars = exprs(VSTEST)), + compare = expected_result, + keys = c("USUBJID", "VSTEST")) }) -## Test 2: Forgot to specify by_vars ---- -test_that("derive_vars_cat Test 2: Forgot to specify by_vars", { +## Test 3: Forgot to specify by_vars ---- +test_that("derive_vars_cat Test 3: Forgot to specify by_vars", { definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, "Height", AVAL >= 160, ">=160", 1, @@ -59,8 +94,8 @@ test_that("derive_vars_cat Test 2: Forgot to specify by_vars", { expect_snapshot_warning(derive_vars_cat(advs, definition)) }) -## Test 3: Error when dataset is not a dataframe ---- -test_that("derive_vars_cat Test 3: Error when dataset is not a dataframe", { +## Test 4: Error when dataset is not a dataframe ---- +test_that("derive_vars_cat Test 4: Error when dataset is not a dataframe", { # Define the condition and categories definition <- exprs( ~condition, ~AVALCAT1, ~AVALCA1N, @@ -75,8 +110,8 @@ test_that("derive_vars_cat Test 3: Error when dataset is not a dataframe", { ) }) -## Test 4: Error when definition is not an exprs object ---- -test_that("derive_vars_cat Test 4: Error when definition is not an exprs object", { +## Test 5: Error when definition is not an exprs object ---- +test_that("derive_vars_cat Test 5: Error when definition is not an exprs object", { definition <- tribble( ~condition, ~AVALCAT1, ~AVALCA1N, "AVAL >= 160", ">=160", 1, @@ -88,8 +123,8 @@ test_that("derive_vars_cat Test 4: Error when definition is not an exprs object" ) }) -## Test 5: Error when required columns are missing from dataset ---- -test_that("derive_vars_cat Test 5: Error when required columns are missing from dataset", { +## Test 6: Error when required columns are missing from dataset ---- +test_that("derive_vars_cat Test 6: Error when required columns are missing from dataset", { # Define the condition and categories (without VSTEST in the dataset) definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, @@ -107,21 +142,45 @@ test_that("derive_vars_cat Test 5: Error when required columns are missing from ) }) -## Test 6: Correct behavior when no conditions are met ---- -test_that("derive_vars_cat Test 6: Correct behavior when no conditions are met", { +## Test 7: Correct behavior when no conditions are met ---- +test_that("derive_vars_cat Test 7: Correct behavior when no conditions are met", { # Define conditions that do not match any rows definition <- exprs( ~condition, ~AVALCAT1, ~AVALCA1N, VSTEST == "Height" & AVAL < 0, "<0", 1 ) - result <- derive_vars_cat(advs, definition) + expected_result <- tibble::tribble( + ~USUBJID, ~VSTEST, ~AVAL, ~AVALCAT1, ~AVALCA1N, + "01-701-1015", "Height", 147.32, NA_character_, NA_real_, + "01-701-1023", "Height", 162.56, NA_character_, NA_real_, + "01-701-1028", "Height", 177.8, NA_character_, NA_real_, + "01-701-1033", "Height", 175.26, NA_character_, NA_real_, + "01-701-1034", "Height", NA, NA_character_, NA_real_, + "01-701-1047", "Height", NA, NA_character_, NA_real_, + "01-701-1097", "Height", 168.91, NA_character_, NA_real_, + "01-701-1111", "Height", 158.24, NA_character_, NA_real_, + "01-701-1115", "Height", 181.61, NA_character_, NA_real_, + "01-701-1118", "Height", 180.34, NA_character_, NA_real_, + "01-701-1015", "Weight", 53.98, NA_character_, NA_real_, + "01-701-1023", "Weight", 78.47, NA_character_, NA_real_, + "01-701-1028", "Weight", 98.88, NA_character_, NA_real_, + "01-701-1033", "Weight", 88.45, NA_character_, NA_real_, + "01-701-1034", "Weight", NA, NA_character_, NA_real_, + "01-701-1047", "Weight", NA, NA_character_, NA_real_, + "01-701-1097", "Weight", 78.02, NA_character_, NA_real_, + "01-701-1111", "Weight", 60.33, NA_character_, NA_real_, + "01-701-1115", "Weight", 78.7, NA_character_, NA_real_, + "01-701-1118", "Weight", 71.67, NA_character_, NA_real_ + ) - expect_snapshot(result) + expect_dfs_equal(base = derive_vars_cat(advs, definition), + compare = expected_result, + keys = c("USUBJID", "VSTEST")) }) -## Test 7: Overlapping conditions handled correctly ---- -test_that("derive_vars_cat Test 7: Overlapping conditions handled correctly", { +## Test 8: Overlapping conditions handled correctly ---- +test_that("derive_vars_cat Test 8: Overlapping conditions handled correctly", { # Define overlapping conditions definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, @@ -130,14 +189,38 @@ test_that("derive_vars_cat Test 7: Overlapping conditions handled correctly", { "Height", AVAL >= 170, ">=170", 1 ) - result <- derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)) + expected_result <- tibble::tribble( + ~USUBJID, ~VSTEST, ~AVAL, ~AVALCAT1, ~AVALCA1N, + "01-701-1015", "Height", 147.32, "<160", 3, + "01-701-1023", "Height", 162.56, "<170", 2, + "01-701-1028", "Height", 177.8, ">=170", 1, + "01-701-1033", "Height", 175.26, ">=170", 1, + "01-701-1034", "Height", NA, NA, NA, + "01-701-1047", "Height", NA, NA, NA, + "01-701-1097", "Height", 168.91, "<170", 2, + "01-701-1111", "Height", 158.24, "<160", 3, + "01-701-1115", "Height", 181.61, ">=170", 1, + "01-701-1118", "Height", 180.34, ">=170", 1, + "01-701-1015", "Weight", 53.98, NA, NA, + "01-701-1023", "Weight", 78.47, NA, NA, + "01-701-1028", "Weight", 98.88, NA, NA, + "01-701-1033", "Weight", 88.45, NA, NA, + "01-701-1034", "Weight", NA, NA, NA, + "01-701-1047", "Weight", NA, NA, NA, + "01-701-1097", "Weight", 78.02, NA, NA, + "01-701-1111", "Weight", 60.33, NA, NA, + "01-701-1115", "Weight", 78.7, NA, NA, + "01-701-1118", "Weight", 71.67, NA, NA + ) - expect_snapshot(result) + expect_dfs_equal(base = derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)), + compare = expected_result, + keys = c("USUBJID", "VSTEST")) }) -## Test 8: Error when condition is missing from `definition` ---- -test_that("derive_vars_cat Test 8: Error when condition is missing from `definition`", { +## Test 9: Error when condition is missing from `definition` ---- +test_that("derive_vars_cat Test 9: Error when condition is missing from `definition`", { # Define the condition but omit the 'condition' column from the definition definition <- exprs( ~AVALCAT1, ~AVALCA1N, @@ -152,8 +235,8 @@ test_that("derive_vars_cat Test 8: Error when condition is missing from `definit ) }) -## Test 9: Conditions for multiple VSTESTs (Height and Weight) ---- -test_that("derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and Weight)", { +## Test 10: Conditions for multiple VSTESTs (Height and Weight) ---- +test_that("derive_vars_cat Test 10: Conditions for multiple VSTESTs (Height and Weight)", { # Define conditions for two different VSTEST values: Height and BILI definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, @@ -163,13 +246,36 @@ test_that("derive_vars_cat Test 9: Conditions for multiple VSTESTs (Height and W "Weight", AVAL < 66.68, "Weight < 66.68", 2 ) - result <- derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)) - - expect_snapshot(result) + expected_result <- tibble::tribble( + ~USUBJID, ~VSTEST, ~AVAL, ~AVALCAT1, ~AVALCA1N, + "01-701-1015", "Height", 147.32, "Height < 160", 2, + "01-701-1023", "Height", 162.56, "Height >= 160", 1, + "01-701-1028", "Height", 177.8, "Height >= 160", 1, + "01-701-1033", "Height", 175.26, "Height >= 160", 1, + "01-701-1034", "Height", NA, NA, NA, + "01-701-1047", "Height", NA, NA, NA, + "01-701-1097", "Height", 168.91, "Height >= 160", 1, + "01-701-1111", "Height", 158.24, "Height < 160", 2, + "01-701-1115", "Height", 181.61, "Height >= 160", 1, + "01-701-1118", "Height", 180.34, "Height >= 160", 1, + "01-701-1015", "Weight", 53.98, "Weight < 66.68", 2, + "01-701-1023", "Weight", 78.47, "Weight >= 66.68", 1, + "01-701-1028", "Weight", 98.88, "Weight >= 66.68", 1, + "01-701-1033", "Weight", 88.45, "Weight >= 66.68", 1, + "01-701-1034", "Weight", NA, NA, NA, + "01-701-1047", "Weight", NA, NA, NA, + "01-701-1097", "Weight", 78.02, "Weight >= 66.68", 1, + "01-701-1111", "Weight", 60.33, "Weight < 66.68", 2, + "01-701-1115", "Weight", 78.7, "Weight >= 66.68", 1, + "01-701-1118", "Weight", 71.67, "Weight >= 66.68", 1 + ) + expect_dfs_equal(base = derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)), + compare = expected_result, + keys = c("USUBJID", "VSTEST")) }) -## Test 10: Adding an extra variable (flag) to the dataset ---- -test_that("derive_vars_cat Test 10: Adding an extra variable (flag) to the dataset", { +## Test 11: Adding an extra variable (flag) to the dataset ---- +test_that("derive_vars_cat Test 11: Adding an extra variable (flag) to the dataset", { # Define conditions and add a third variable (flag) that is TRUE or FALSE definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, ~extra_var, @@ -177,13 +283,36 @@ test_that("derive_vars_cat Test 10: Adding an extra variable (flag) to the datas "Height", AVAL < 160, "<160", 2, FALSE ) - result <- derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)) - - expect_snapshot(result) + expected_result <- tibble::tribble( + ~USUBJID, ~VSTEST, ~AVAL, ~AVALCAT1, ~AVALCA1N, ~extra_var, + "01-701-1015", "Height", 147.32, "<160", 2, FALSE, + "01-701-1023", "Height", 162.56, ">=160", 1, TRUE, + "01-701-1028", "Height", 177.8, ">=160", 1, TRUE, + "01-701-1033", "Height", 175.26, ">=160", 1, TRUE, + "01-701-1034", "Height", NA, NA, NA, NA, + "01-701-1047", "Height", NA, NA, NA, NA, + "01-701-1097", "Height", 168.91, ">=160", 1, TRUE, + "01-701-1111", "Height", 158.24, "<160", 2, FALSE, + "01-701-1115", "Height", 181.61, ">=160", 1, TRUE, + "01-701-1118", "Height", 180.34, ">=160", 1, TRUE, + "01-701-1015", "Weight", 53.98, NA, NA, NA, + "01-701-1023", "Weight", 78.47, NA, NA, NA, + "01-701-1028", "Weight", 98.88, NA, NA, NA, + "01-701-1033", "Weight", 88.45, NA, NA, NA, + "01-701-1034", "Weight", NA, NA, NA, NA, + "01-701-1047", "Weight", NA, NA, NA, NA, + "01-701-1097", "Weight", 78.02, NA, NA, NA, + "01-701-1111", "Weight", 60.33, NA, NA, NA, + "01-701-1115", "Weight", 78.7, NA, NA, NA, + "01-701-1118", "Weight", 71.67, NA, NA, NA + ) + expect_dfs_equal(base = derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)), + compare = expected_result, + keys = c("USUBJID", "VSTEST")) }) -## Test 11: Wrong input for by_vars ---- -test_that("derive_vars_cat Test 11: Wrong input for by_vars", { +## Test 12: Wrong input for by_vars ---- +test_that("derive_vars_cat Test 12: Wrong input for by_vars", { # Define conditions definition <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, @@ -196,8 +325,8 @@ test_that("derive_vars_cat Test 11: Wrong input for by_vars", { ) }) -## Test 12: definition has wrong shape ---- -test_that("derive_vars_cat Test 12: definition has wrong shape", { +## Test 13: definition has wrong shape ---- +test_that("derive_vars_cat Test 13: definition has wrong shape", { # Define conditions definition_wrong_shape <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, From ab4390bd89f09b8526ac05d0c6ea94105668200d Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 15:09:27 +0000 Subject: [PATCH 66/83] fix template --- inst/templates/ad_adeg.R | 24 +++++----- man/derive_vars_cat.Rd | 7 ++- man/extend_condition.Rd | 27 +++++++++++ tests/testthat/test-derive_vars_cat.R | 64 ++++++++++++++++----------- vignettes/.build.timestamp | 0 5 files changed, 80 insertions(+), 42 deletions(-) create mode 100644 man/extend_condition.Rd create mode 100644 vignettes/.build.timestamp diff --git a/inst/templates/ad_adeg.R b/inst/templates/ad_adeg.R index fbf9f11cd..aadfc65ef 100644 --- a/inst/templates/ad_adeg.R +++ b/inst/templates/ad_adeg.R @@ -56,18 +56,18 @@ range_lookup <- tibble::tribble( # Assign AVALCAx avalcax_lookup <- exprs( - ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, - "QT", AVAL <= 450, "<= 450 msec", 1, - "QT", AVAL > 450 & AVAL <= 480, ">450<=480 msec", 2, - "QT", AVAL > 480 & AVAL <= 500, ">480<=500 msec", 3, - "QT", AVAL > 500, ">500 msec", 4 + ~condition, ~AVALCAT1, ~AVALCA1N, + starts_with(PARAMCD, "QT") & AVAL <= 450, "<= 450 msec", 1, + starts_with(PARAMCD, "QT") & AVAL > 450 & AVAL <= 480, ">450<=480 msec", 2, + starts_with(PARAMCD, "QT") & AVAL > 480 & AVAL <= 500, ">480<=500 msec", 3, + starts_with(PARAMCD, "QT") & AVAL > 500, ">500 msec", 4 ) # Assign CHGCAx chgcax_lookup <- exprs( - ~PARAMCD, ~condition, ~CHGCAT1, ~CHGCAT1N, - "QT", CHG <= 30, "<= 30 msec", 1, - "QT", CHG > 30 & CHG <= 60, ">30<=60 msec", 2, - "QT", CHG > 60, ">60 msec", 3 + ~condition, ~CHGCAT1, ~CHGCAT1N, + starts_with(PARAMCD, "QT") & CHG <= 30, "<= 30 msec", 1, + starts_with(PARAMCD, "QT") & CHG > 30 & CHG <= 60, ">30<=60 msec", 2, + starts_with(PARAMCD, "QT") & CHG > 60, ">60 msec", 3 ) # Derivations ---- @@ -295,13 +295,11 @@ adeg <- adeg %>% ) %>% # Derive AVALCA1N and AVALCAT1 derive_vars_cat( - definition = avalcax_lookup, - by_vars = exprs(PARAMCD) + definition = avalcax_lookup ) %>% # Derive CHGCAT1N and CHGCAT1 derive_vars_cat( - definition = chgcax_lookup, - by_vars = exprs(PARAMCD) + definition = chgcax_lookup ) %>% # Derive PARAM and PARAMN derive_vars_merged( diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index cee2ab448..72101f371 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -45,7 +45,7 @@ The categorization variables are set to NA for records not matching any of the by groups in \code{definition}.} } \value{ -data frame +The input dataset with the new variables defined in \code{definition} added } \description{ Derive Categorization Variables Like \code{AVALCATy} and \code{AVALCAyN} @@ -111,7 +111,7 @@ derive_vars_cat( dataset = advs, definition = definition ) -# using by_vars: +# Using by_vars: definition2 <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, "Height", AVAL > 160, ">160 cm", 1, @@ -161,8 +161,7 @@ adlb \%>\% derive_vars_cat( definition = definition_mcrit, by_vars = exprs(PARAM) - ) \%>\% - print() + ) } \seealso{ General Derivation Functions for all ADaMs that returns variable appended to dataset: diff --git a/man/extend_condition.Rd b/man/extend_condition.Rd new file mode 100644 index 000000000..e47e6314f --- /dev/null +++ b/man/extend_condition.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/derive_vars_cat.R +\name{extend_condition} +\alias{extend_condition} +\title{Extend a condition string by adding a new condition based on a variable and its value} +\usage{ +extend_condition(cond, var, is) +} +\arguments{ +\item{cond}{A character string representing an existing condition.} + +\item{var}{A character string representing the name of the variable to check.} + +\item{is}{A character string representing the value the variable should be equal to.} +} +\value{ +A character string representing the extended condition. +} +\description{ +This internal helper function extends a condition string by appending a new condition +that checks if a variable equals a specific value. +} +\examples{ +# Extend an existing condition to include a check for 'AGE == "30"' +extend_condition("SEX == 'M'", "AGE", "30") +} +\keyword{internal} diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index 42b70fa82..6eb0a44cc 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -55,12 +55,15 @@ test_that("derive_vars_cat Test 1: Basic functionality without by_vars", { VSTEST == "Height" & AVAL < 160, "<160", 2 ) - expect_dfs_equal(base = - derive_vars_cat( - advs, - definition), - compare = expected_result, - keys = c("USUBJID", "VSTEST")) + expect_dfs_equal( + base = + derive_vars_cat( + advs, + definition + ), + compare = expected_result, + keys = c("USUBJID", "VSTEST") + ) }) ## Test 2: Basic functionality with by_vars ---- @@ -74,13 +77,16 @@ test_that("derive_vars_cat Test 2: Basic functionality with by_vars", { - expect_dfs_equal(base = - derive_vars_cat( - advs, - definition, - by_vars = exprs(VSTEST)), - compare = expected_result, - keys = c("USUBJID", "VSTEST")) + expect_dfs_equal( + base = + derive_vars_cat( + advs, + definition, + by_vars = exprs(VSTEST) + ), + compare = expected_result, + keys = c("USUBJID", "VSTEST") + ) }) ## Test 3: Forgot to specify by_vars ---- @@ -174,9 +180,11 @@ test_that("derive_vars_cat Test 7: Correct behavior when no conditions are met", "01-701-1118", "Weight", 71.67, NA_character_, NA_real_ ) - expect_dfs_equal(base = derive_vars_cat(advs, definition), - compare = expected_result, - keys = c("USUBJID", "VSTEST")) + expect_dfs_equal( + base = derive_vars_cat(advs, definition), + compare = expected_result, + keys = c("USUBJID", "VSTEST") + ) }) ## Test 8: Overlapping conditions handled correctly ---- @@ -213,9 +221,11 @@ test_that("derive_vars_cat Test 8: Overlapping conditions handled correctly", { "01-701-1118", "Weight", 71.67, NA, NA ) - expect_dfs_equal(base = derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)), - compare = expected_result, - keys = c("USUBJID", "VSTEST")) + expect_dfs_equal( + base = derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)), + compare = expected_result, + keys = c("USUBJID", "VSTEST") + ) }) @@ -269,9 +279,11 @@ test_that("derive_vars_cat Test 10: Conditions for multiple VSTESTs (Height and "01-701-1115", "Weight", 78.7, "Weight >= 66.68", 1, "01-701-1118", "Weight", 71.67, "Weight >= 66.68", 1 ) - expect_dfs_equal(base = derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)), - compare = expected_result, - keys = c("USUBJID", "VSTEST")) + expect_dfs_equal( + base = derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)), + compare = expected_result, + keys = c("USUBJID", "VSTEST") + ) }) ## Test 11: Adding an extra variable (flag) to the dataset ---- @@ -306,9 +318,11 @@ test_that("derive_vars_cat Test 11: Adding an extra variable (flag) to the datas "01-701-1115", "Weight", 78.7, NA, NA, NA, "01-701-1118", "Weight", 71.67, NA, NA, NA ) - expect_dfs_equal(base = derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)), - compare = expected_result, - keys = c("USUBJID", "VSTEST")) + expect_dfs_equal( + base = derive_vars_cat(advs, definition, by_vars = exprs(VSTEST)), + compare = expected_result, + keys = c("USUBJID", "VSTEST") + ) }) ## Test 12: Wrong input for by_vars ---- diff --git a/vignettes/.build.timestamp b/vignettes/.build.timestamp new file mode 100644 index 000000000..e69de29bb From 7c089eb1975776757e56e36823e999e32f0b4299 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 15:11:30 +0000 Subject: [PATCH 67/83] switch function --- inst/templates/ad_adeg.R | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/inst/templates/ad_adeg.R b/inst/templates/ad_adeg.R index aadfc65ef..cd960c2f5 100644 --- a/inst/templates/ad_adeg.R +++ b/inst/templates/ad_adeg.R @@ -57,17 +57,17 @@ range_lookup <- tibble::tribble( # Assign AVALCAx avalcax_lookup <- exprs( ~condition, ~AVALCAT1, ~AVALCA1N, - starts_with(PARAMCD, "QT") & AVAL <= 450, "<= 450 msec", 1, - starts_with(PARAMCD, "QT") & AVAL > 450 & AVAL <= 480, ">450<=480 msec", 2, - starts_with(PARAMCD, "QT") & AVAL > 480 & AVAL <= 500, ">480<=500 msec", 3, - starts_with(PARAMCD, "QT") & AVAL > 500, ">500 msec", 4 + startsWith(PARAMCD, "QT") & AVAL <= 450, "<= 450 msec", 1, + startsWith(PARAMCD, "QT") & AVAL > 450 & AVAL <= 480, ">450<=480 msec", 2, + startsWith(PARAMCD, "QT") & AVAL > 480 & AVAL <= 500, ">480<=500 msec", 3, + startsWith(PARAMCD, "QT") & AVAL > 500, ">500 msec", 4 ) # Assign CHGCAx chgcax_lookup <- exprs( ~condition, ~CHGCAT1, ~CHGCAT1N, - starts_with(PARAMCD, "QT") & CHG <= 30, "<= 30 msec", 1, - starts_with(PARAMCD, "QT") & CHG > 30 & CHG <= 60, ">30<=60 msec", 2, - starts_with(PARAMCD, "QT") & CHG > 60, ">60 msec", 3 + startsWith(PARAMCD, "QT") & CHG <= 30, "<= 30 msec", 1, + startsWith(PARAMCD, "QT") & CHG > 30 & CHG <= 60, ">30<=60 msec", 2, + startsWith(PARAMCD, "QT") & CHG > 60, ">60 msec", 3 ) # Derivations ---- From 023a535b43f52efdce9999e7c3bcab53e00954d8 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 15:12:50 +0000 Subject: [PATCH 68/83] fix alignment --- inst/templates/ad_adeg.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/templates/ad_adeg.R b/inst/templates/ad_adeg.R index cd960c2f5..b9ed092c0 100644 --- a/inst/templates/ad_adeg.R +++ b/inst/templates/ad_adeg.R @@ -56,7 +56,7 @@ range_lookup <- tibble::tribble( # Assign AVALCAx avalcax_lookup <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, + ~condition, ~AVALCAT1, ~AVALCA1N, startsWith(PARAMCD, "QT") & AVAL <= 450, "<= 450 msec", 1, startsWith(PARAMCD, "QT") & AVAL > 450 & AVAL <= 480, ">450<=480 msec", 2, startsWith(PARAMCD, "QT") & AVAL > 480 & AVAL <= 500, ">480<=500 msec", 3, @@ -64,7 +64,7 @@ avalcax_lookup <- exprs( ) # Assign CHGCAx chgcax_lookup <- exprs( - ~condition, ~CHGCAT1, ~CHGCAT1N, + ~condition, ~CHGCAT1, ~CHGCAT1N, startsWith(PARAMCD, "QT") & CHG <= 30, "<= 30 msec", 1, startsWith(PARAMCD, "QT") & CHG > 30 & CHG <= 60, ">30<=60 msec", 2, startsWith(PARAMCD, "QT") & CHG > 60, ">60 msec", 3 From 7e27b3a6da3424bcdb8179a83ec4c0caff23e25a Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 15:40:22 +0000 Subject: [PATCH 69/83] tryout --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 96f190eaf..51a9c8022 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -247,7 +247,7 @@ derive_vars_cat <- function(dataset, #' @return A character string representing the extended condition. #' @examples #' # Extend an existing condition to include a check for 'AGE == "30"' -#' extend_condition("SEX == 'M'", "AGE", "30") +#' admiral:::extend_condition("SEX == 'M'", "AGE", "30") #' @keywords internal extend_condition <- function(cond, var, is) { paste(cond, " & ", var, " == '", is, "'", sep = "") From 867b66f21a02b08174f2caab5f10217d29473297 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Wed, 25 Sep 2024 15:58:32 +0000 Subject: [PATCH 70/83] add ::: to internal function --- man/extend_condition.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/extend_condition.Rd b/man/extend_condition.Rd index e47e6314f..da3ceb377 100644 --- a/man/extend_condition.Rd +++ b/man/extend_condition.Rd @@ -22,6 +22,6 @@ that checks if a variable equals a specific value. } \examples{ # Extend an existing condition to include a check for 'AGE == "30"' -extend_condition("SEX == 'M'", "AGE", "30") +admiral:::extend_condition("SEX == 'M'", "AGE", "30") } \keyword{internal} From 86601795a60bcfb3af1a9f519b64274a2e35a5bb Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Thu, 26 Sep 2024 15:09:50 +0200 Subject: [PATCH 71/83] Update R/derive_vars_cat.R Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 51a9c8022..0508ef762 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -106,7 +106,7 @@ #' dataset = advs, #' definition = definition #' ) - +#' #' # Using by_vars: #' definition2 <- exprs( #' ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, From 8caf2271660e732007aeabe33d017aa0d8c827c5 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Thu, 26 Sep 2024 15:10:26 +0200 Subject: [PATCH 72/83] Update R/derive_vars_cat.R Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- R/derive_vars_cat.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 0508ef762..fd1d38510 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -184,10 +184,10 @@ derive_vars_cat <- function(dataset, # Catch the error and append your own message cli_abort( paste( - "Failed to convert `definition` to `tibble`.", - "`definition` should be specified similarly to how you would", - "specify a `tibble` using the `tribble()` function so it", - "can be converted to `tibble` using `tribble()`." + "Failed to convert {.arg definition} to {.cls tibble}.", + "{.arg definition} should be specified similarly to how you would", + "specify a {.cls tibble} using the {.fun tibble::tribble}` function so it", + "can be converted to {.cls tibble}` using {.fun tibble::tribble}`." ), e$message ) From e7882f049e47edf1de4c28f0ab97ed9500c0da60 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Thu, 26 Sep 2024 15:10:57 +0200 Subject: [PATCH 73/83] Update R/derive_vars_cat.R Co-authored-by: Stefan Bundfuss <80953585+bundfussr@users.noreply.github.com> --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index fd1d38510..1e2d61d20 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -164,7 +164,7 @@ derive_vars_cat <- function(dataset, assert_expr_list(definition) assert_vars(by_vars, optional = TRUE) if (length(by_vars) > 1) { - cli_abort("`by_vars` must contain just one variable, e.g. `exprs(PARAMCD)`") + cli_abort("{.arg by_vars} must contain just one variable, e.g. {.code exprs(PARAMCD)}") } assert_data_frame(dataset, From 96bdd8d2dbdf9c860f61b157bafa7ffead604f45 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 26 Sep 2024 14:13:51 +0000 Subject: [PATCH 74/83] aligned again --- R/derive_vars_cat.R | 16 ++++---- tests/testthat/_snaps/derive_vars_cat.md | 8 +--- tests/testthat/test-derive_vars_cat.R | 38 ++++------------- vignettes/bds_exposure.Rmd | 41 +++++++++---------- vignettes/bds_finding.Rmd | 52 ++++++++++++------------ 5 files changed, 66 insertions(+), 89 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 1e2d61d20..e504be73b 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -183,13 +183,15 @@ derive_vars_cat <- function(dataset, error = function(e) { # Catch the error and append your own message cli_abort( - paste( - "Failed to convert {.arg definition} to {.cls tibble}.", - "{.arg definition} should be specified similarly to how you would", - "specify a {.cls tibble} using the {.fun tibble::tribble}` function so it", - "can be converted to {.cls tibble}` using {.fun tibble::tribble}`." - ), - e$message + c( + paste( + "Failed to convert {.arg definition} to {.cls tibble}.", + "{.arg definition} should be specified similarly to how you would", + "specify a {.cls tibble} using the {.fun tibble::tribble} function so it", + "can be converted to {.cls tibble} using {.fun tibble::tribble}." + ), + e$message + ) ) } ) diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index 372243c03..616ac7960 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -4,12 +4,8 @@ Did you forget to specify `by_vars`, or are you rerunning your code? -# derive_vars_cat Test 5: Error when definition is not an exprs object - - Argument `definition` must be a list of expressions but is a tibble. - i To create a list of expressions use `exprs()`. - # derive_vars_cat Test 13: definition has wrong shape - Failed to convert `definition` to `tibble`. `definition` should be specified similarly to how you would specify a `tibble` using the `tribble()` function so it can be converted to `tibble` using `tribble()`. + Failed to convert `definition` to . `definition` should be specified similarly to how you would specify a using the `tibble::tribble()` function so it can be converted to using `tibble::tribble()`. + Data must be rectangular. diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index 6eb0a44cc..d4642565f 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -1,28 +1,3 @@ -# Load the advs dataset -advs <- tibble::tribble( - ~USUBJID, ~VSTEST, ~AVAL, - "01-701-1015", "Height", 147.32, - "01-701-1015", "Weight", 53.98, - "01-701-1023", "Height", 162.56, - "01-701-1023", "Weight", 78.47, - "01-701-1028", "Height", 177.8, - "01-701-1028", "Weight", 98.88, - "01-701-1033", "Height", 175.26, - "01-701-1033", "Weight", 88.45, - "01-701-1034", "Height", NA, - "01-701-1034", "Weight", NA, - "01-701-1047", "Height", NA, - "01-701-1047", "Weight", NA, - "01-701-1097", "Height", 168.91, - "01-701-1097", "Weight", 78.02, - "01-701-1111", "Height", 158.24, - "01-701-1111", "Weight", 60.33, - "01-701-1115", "Height", 181.61, - "01-701-1115", "Weight", 78.7, - "01-701-1118", "Height", 180.34, - "01-701-1118", "Weight", 71.67 -) %>% arrange(VSTEST) - expected_result <- tibble::tribble( ~USUBJID, ~VSTEST, ~AVAL, ~AVALCAT1, ~AVALCA1N, "01-701-1015", "Height", 147.32, "<160", 2, @@ -46,6 +21,10 @@ expected_result <- tibble::tribble( "01-701-1115", "Weight", 78.7, NA, NA, "01-701-1118", "Weight", 71.67, NA, NA ) + +advs <- expected_result %>% select( + USUBJID, VSTEST, AVAL +) ## Test 1: Basic functionality without by_vars ---- test_that("derive_vars_cat Test 1: Basic functionality without by_vars", { # Define the condition and categories @@ -124,8 +103,9 @@ test_that("derive_vars_cat Test 5: Error when definition is not an exprs object" "AVAL < 160", "<160", 2 ) # Snapshot the error message - expect_snapshot_error( - derive_vars_cat(advs, definition) + expect_error( + derive_vars_cat(advs, definition), + class = "assert_expr_list" ) }) @@ -152,8 +132,8 @@ test_that("derive_vars_cat Test 6: Error when required columns are missing from test_that("derive_vars_cat Test 7: Correct behavior when no conditions are met", { # Define conditions that do not match any rows definition <- exprs( - ~condition, ~AVALCAT1, ~AVALCA1N, - VSTEST == "Height" & AVAL < 0, "<0", 1 + ~condition, ~AVALCAT1, ~AVALCA1N, + VSTEST == "Height" & AVAL < 0, "<0", 1 ) expected_result <- tibble::tribble( diff --git a/vignettes/bds_exposure.Rmd b/vignettes/bds_exposure.Rmd index 0b4028564..673f08e76 100644 --- a/vignettes/bds_exposure.Rmd +++ b/vignettes/bds_exposure.Rmd @@ -41,7 +41,7 @@ otherwise specified.* * [Create 1:1 Mapping Records](#onetoone) * [Create Summary Records](#summaryrec) * [Assign `PARAMCD`, `PARAMN`, etc. from Reference Tables](#paramcd) -* [Derive Categorization Variables (`AVALCATx`)](#cat) +* [Derive Categorization Variables (`AVALCATy`)](#cat) * [Assign `ASEQ`](#aseq) * [Add ADSL variables `ASEQ`](#adsl_vars) * [Add Labels and Attributes](#attributes) @@ -514,18 +514,18 @@ TNDOSINT | Overall dose intensity (%) | 12 ```{r eval=TRUE, include=FALSE, echo=FALSE} param_lookup <- tribble( - ~PARAMCD, ~PARAM, ~PARAMN, - "DURD", "Study drug duration during constant dosing interval (days)", 1, - "DOSE", "Dose administered during constant dosing interval (mg)", 2, - "PLDOSE", "Planned dose during constant dosing interval (mg)", 3, - "ADJ", "Dose adjusted during constant dosing interval", 4, - "ADJAE", "Dose adjusted due to AE during constant dosing interval", 5, - "TDURD", "Overall duration (days)", 6, - "TDOSE", "Total dose administered (mg)", 7, - "TPDOSE", "Total planned dose (mg)", 9, - "TADJ", "Dose adjusted during study", 10, - "TADJAE", "Dose adjusted during study due to AE", 11, - "TNDOSINT", "Overall dose intensity (%)", 12 + ~PARAMCD, ~PARAM, ~PARAMN, + "DURD", "Study drug duration during constant dosing interval (days)", 1, + "DOSE", "Dose administered during constant dosing interval (mg)", 2, + "PLDOSE", "Planned dose during constant dosing interval (mg)", 3, + "ADJ", "Dose adjusted during constant dosing interval", 4, + "ADJAE", "Dose adjusted due to AE during constant dosing interval", 5, + "TDURD", "Overall duration (days)", 6, + "TDOSE", "Total dose administered (mg)", 7, + "TPDOSE", "Total planned dose (mg)", 9, + "TADJ", "Dose adjusted during study", 10, + "TADJAE", "Dose adjusted during study due to AE", 11, + "TNDOSINT", "Overall dose intensity (%)", 12 ) ``` @@ -549,17 +549,16 @@ We can use the `derive_vars_cat()` function to derive the categorization variabl ```{r eval=TRUE, echo=TRUE} avalcax_lookup <- exprs( - ~PARAMCD, ~condition, ~AVALCAT1, - "TDURD", AVAL >= 90, ">= 90 days", + ~PARAMCD, ~condition, ~AVALCAT1, + "TDURD", AVAL >= 90, ">= 90 days", "TDURD", AVAL >= 30 & AVAL < 90, ">= 30 and < 90 days", - "TDURD", AVAL < 30, "< 30 days", - "TDOSE", AVAL < 1000, "< 1000 mg", - "TDOSE", AVAL >= 1000, ">= 1000 mg", - "TPDOSE", AVAL < 1000, "< 1000 mg", - "TPDOSE", AVAL >= 1000, ">= 1000 mg" + "TDURD", AVAL < 30, "< 30 days", + "TDOSE", AVAL < 1000, "< 1000 mg", + "TDOSE", AVAL >= 1000, ">= 1000 mg", + "TPDOSE", AVAL < 1000, "< 1000 mg", + "TPDOSE", AVAL >= 1000, ">= 1000 mg" ) - adex <- adex %>% derive_vars_cat( definition = avalcax_lookup, diff --git a/vignettes/bds_finding.Rmd b/vignettes/bds_finding.Rmd index b3fe3b2a7..ea28cb87f 100644 --- a/vignettes/bds_finding.Rmd +++ b/vignettes/bds_finding.Rmd @@ -44,7 +44,7 @@ otherwise specified.* * [Derive Analysis Flags (e.g. `ANL01FL`)](#analysisrec) * [Assign Treatment (`TRTA`, `TRTP`)](#treatment) * [Assign `ASEQ`](#aseq) -* [Derive Categorization Variables (`AVALCATx`)](#cat) +* [Derive Categorization Variables (`AVALCATy`)](#cat) * [Derive Criterion Variables (`CRITy`, `CRITyFL`, `CRITyFLN`)](#crit_vars) * [Add ADSL variables](#adsl_vars) * [Derive New Rows](#additional) @@ -214,16 +214,16 @@ TEMP | TEMP | Temperature (C) | 7 | Vital Sign | 2 This lookup may now be joined to the source data: ```{r eval=TRUE, include=FALSE} -param_lookup <- tribble( - ~VSTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, ~PARCAT1, ~PARCAT1N, - "HEIGHT", "HEIGHT", "Height (cm)", 1, "Subject Characteristic", 1, - "WEIGHT", "WEIGHT", "Weight (kg)", 2, "Subject Characteristic", 1, - "DIABP", "DIABP", "Diastolic Blood Pressure (mmHg)", 3, "Vital Sign", 2, - "MAP", "MAP", "Mean Arterial Pressure (mmHg)", 4, "Vital Sign", 2, - "BSA", "BSA", "Body Surface Area (m^2)", 5, "Vital Sign", 2, - "PULSE", "PULSE", "Pulse Rate (beats/min)", 6, "Vital Sign", 2, - "SYSBP", "SYSBP", "Systolic Blood Pressure (mmHg)", 7, "Vital Sign", 2, - "TEMP", "TEMP", "Temperature (C)", 8, "Vital Sign", 2 +param_lookup <- tibble::tribble( + ~VSTESTCD, ~PARAMCD, ~PARAM, ~PARAMN, ~PARCAT1, ~PARCAT1N, + "HEIGHT", "HEIGHT", "Height (cm)", 1, "Subject Characteristic", 1, + "WEIGHT", "WEIGHT", "Weight (kg)", 2, "Subject Characteristic", 1, + "DIABP", "DIABP", "Diastolic Blood Pressure (mmHg)", 3, "Vital Sign", 2, + "MAP", "MAP", "Mean Arterial Pressure (mmHg)", 4, "Vital Sign", 2, + "BSA", "BSA", "Body Surface Area (m^2)", 5, "Vital Sign", 2, + "PULSE", "PULSE", "Pulse Rate (beats/min)", 6, "Vital Sign", 2, + "SYSBP", "SYSBP", "Systolic Blood Pressure (mmHg)", 7, "Vital Sign", 2, + "TEMP", "TEMP", "Temperature (C)", 8, "Vital Sign", 2 ) attr(param_lookup$VSTESTCD, "label") <- "Vital Signs Test Short Name" ``` @@ -345,11 +345,11 @@ created with a function call. See example below for `PARAMCD` = `QTCF`. ```{r eval=FALSE} adeg <- tibble::tribble( - ~USUBJID, ~EGSTRESU, ~PARAMCD, ~AVAL, ~VISIT, - "P01", "msec", "QT", 350, "CYCLE 1 DAY 1", - "P01", "msec", "QT", 370, "CYCLE 2 DAY 1", - "P01", "msec", "RR", 842, "CYCLE 1 DAY 1", - "P01", "msec", "RR", 710, "CYCLE 2 DAY 1" + ~USUBJID, ~EGSTRESU, ~PARAMCD, ~AVAL, ~VISIT, + "P01", "msec", "QT", 350, "CYCLE 1 DAY 1", + "P01", "msec", "QT", 370, "CYCLE 2 DAY 1", + "P01", "msec", "RR", 842, "CYCLE 1 DAY 1", + "P01", "msec", "RR", 710, "CYCLE 2 DAY 1" ) adeg <- derive_param_qtc( @@ -366,11 +366,11 @@ for lab differentials converted to absolute values. See example below: ```{r eval=FALSE} adlb <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~AVAL, ~PARAM, ~VISIT, - "P01", "WBC", 33, "Leukocyte Count (10^9/L)", "CYCLE 1 DAY 1", - "P01", "WBC", 38, "Leukocyte Count (10^9/L)", "CYCLE 2 DAY 1", - "P01", "LYMLE", 0.90, "Lymphocytes (fraction of 1)", "CYCLE 1 DAY 1", - "P01", "LYMLE", 0.70, "Lymphocytes (fraction of 1)", "CYCLE 2 DAY 1" + ~USUBJID, ~PARAMCD, ~AVAL, ~PARAM, ~VISIT, + "P01", "WBC", 33, "Leukocyte Count (10^9/L)", "CYCLE 1 DAY 1", + "P01", "WBC", 38, "Leukocyte Count (10^9/L)", "CYCLE 2 DAY 1", + "P01", "LYMLE", 0.90, "Lymphocytes (fraction of 1)", "CYCLE 1 DAY 1", + "P01", "LYMLE", 0.70, "Lymphocytes (fraction of 1)", "CYCLE 2 DAY 1" ) derive_param_wbc_abs( @@ -515,10 +515,10 @@ and `ref_end_date = AP01EDT`. advs_pre <- select(advs, -ONTRTFL) advs <- tibble::tribble( - ~USUBJID, ~ASTDT, ~AP01SDT, ~AP01EDT, ~AENDT, + ~USUBJID, ~ASTDT, ~AP01SDT, ~AP01EDT, ~AENDT, "P01", ymd("2020-03-15"), ymd("2020-01-01"), ymd("2020-03-01"), ymd("2020-12-01"), "P02", ymd("2019-04-30"), ymd("2020-01-01"), ymd("2020-03-01"), ymd("2020-03-15"), - "P03", ymd("2019-04-30"), ymd("2020-01-01"), ymd("2020-03-01"), NA, + "P03", ymd("2019-04-30"), ymd("2020-01-01"), ymd("2020-03-01"), NA, ) ``` @@ -852,9 +852,9 @@ We can use the `derive_vars_cat()` function to derive the categorization variabl ```{r eval=TRUE} avalcat_lookup <- exprs( - ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, - "HEIGHT", AVAL > 140, ">140 cm", 1, - "HEIGHT", AVAL <= 140, "<= 140 cm", 2 + ~PARAMCD, ~condition, ~AVALCAT1, ~AVALCA1N, + "HEIGHT", AVAL > 140, ">140 cm", 1, + "HEIGHT", AVAL <= 140, "<= 140 cm", 2 ) advs <- advs %>% derive_vars_cat( From 15c100784dd588d382de1bfa9678bf166528393a Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Thu, 26 Sep 2024 14:24:55 +0000 Subject: [PATCH 75/83] update manual --- man/derive_vars_cat.Rd | 1 + 1 file changed, 1 insertion(+) diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 72101f371..06f74a1aa 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -111,6 +111,7 @@ derive_vars_cat( dataset = advs, definition = definition ) + # Using by_vars: definition2 <- exprs( ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, From 5a6c6ecab36855cd78709e2f59c26282e375a4a0 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Mon, 30 Sep 2024 08:42:59 +0200 Subject: [PATCH 76/83] Update R/derive_vars_cat.R Co-authored-by: Ben Straub --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index e504be73b..23c1b88d8 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -4,7 +4,7 @@ #' @param definition List of expressions created by `exprs()`. #' Must be in rectangular format and specified using the same syntax as when creating #' a `tibble` using the `tribble()` function. -#' The `definition` object it will be converted to a `tibble` using the `tribble()` function. +#' The `definition` object will be converted to a `tibble` using `tribble()` inside this function. #' #' Must contain: #' - the column `condition` which evaluates to a logic in `dataset`. From 0b803eef053806575761ea584d53500ac31b199e Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Mon, 30 Sep 2024 08:43:10 +0200 Subject: [PATCH 77/83] Update R/derive_vars_cat.R Co-authored-by: Ben Straub --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 23c1b88d8..3fe1c3a0e 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -7,7 +7,7 @@ #' The `definition` object will be converted to a `tibble` using `tribble()` inside this function. #' #' Must contain: -#' - the column `condition` which evaluates to a logic in `dataset`. +#' - the column `condition` which will be converted to a logical expression and used on the `dataset` input. #' - at least one additional column with the new column name and the category value. #' - the column specified in `by_vars` (if `by_vars` is specified) #' From b3a925a32b70e0bbda56016143e2989bff2ae178 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Mon, 30 Sep 2024 08:43:19 +0200 Subject: [PATCH 78/83] Update R/derive_vars_cat.R Co-authored-by: Ben Straub --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 3fe1c3a0e..4620db089 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -8,7 +8,7 @@ #' #' Must contain: #' - the column `condition` which will be converted to a logical expression and used on the `dataset` input. -#' - at least one additional column with the new column name and the category value. +#' - at least one additional column with the new column name and the category value(s) used by the logical expression. #' - the column specified in `by_vars` (if `by_vars` is specified) #' #' e.g. if `by_vars` is not specified: From 05f973e607276c72e85e7660a41f43ec33da4bc9 Mon Sep 17 00:00:00 2001 From: StefanThoma <40463122+StefanThoma@users.noreply.github.com> Date: Mon, 30 Sep 2024 08:43:28 +0200 Subject: [PATCH 79/83] Update R/derive_vars_cat.R Co-authored-by: Ben Straub --- R/derive_vars_cat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index 4620db089..ae4a2a24f 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -33,7 +33,7 @@ #' Allows for specifying by groups, e.g. `exprs(PARAMCD)`. #' Variable must be present in both `dataset` and `definition`. #' The conditions in `definition` are applied only to those records that match `by_vars`. -#' The categorization variables are set to NA for records +#' The categorization variables are set to `NA` for records #' not matching any of the by groups in `definition`. #' #' From 09097ac5c0ea5bee059213c9e2e0d41192550f42 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Mon, 30 Sep 2024 07:02:10 +0000 Subject: [PATCH 80/83] added test for error --- man/derive_vars_cat.Rd | 8 ++++---- tests/testthat/_snaps/derive_vars_cat.md | 4 ++++ tests/testthat/test-derive_vars_cat.R | 16 ++++++++++++++++ vignettes/.build.timestamp | 0 4 files changed, 24 insertions(+), 4 deletions(-) delete mode 100644 vignettes/.build.timestamp diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 06f74a1aa..2e510f1c1 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -14,12 +14,12 @@ The variables specified by the \code{by_vars} and \code{definition} arguments ar \item{definition}{List of expressions created by \code{exprs()}. Must be in rectangular format and specified using the same syntax as when creating a \code{tibble} using the \code{tribble()} function. -The \code{definition} object it will be converted to a \code{tibble} using the \code{tribble()} function. +The \code{definition} object will be converted to a \code{tibble} using \code{tribble()} inside this function. Must contain: \itemize{ -\item the column \code{condition} which evaluates to a logic in \code{dataset}. -\item at least one additional column with the new column name and the category value. +\item the column \code{condition} which will be converted to a logical expression and used on the \code{dataset} input. +\item at least one additional column with the new column name and the category value(s) used by the logical expression. \item the column specified in \code{by_vars} (if \code{by_vars} is specified) } @@ -41,7 +41,7 @@ e.g. if \code{by_vars} is specified as \code{exprs(VSTEST)}: Allows for specifying by groups, e.g. \code{exprs(PARAMCD)}. Variable must be present in both \code{dataset} and \code{definition}. The conditions in \code{definition} are applied only to those records that match \code{by_vars}. -The categorization variables are set to NA for records +The categorization variables are set to \code{NA} for records not matching any of the by groups in \code{definition}.} } \value{ diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index 616ac7960..b5b2dc2df 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -9,3 +9,7 @@ Failed to convert `definition` to . `definition` should be specified similarly to how you would specify a using the `tibble::tribble()` function so it can be converted to using `tibble::tribble()`. Data must be rectangular. +# derive_vars_cat Test 14: two by_vars variables + + `by_vars` must contain just one variable, e.g. `exprs(PARAMCD)` + diff --git a/tests/testthat/test-derive_vars_cat.R b/tests/testthat/test-derive_vars_cat.R index d4642565f..d3cb6e6cd 100644 --- a/tests/testthat/test-derive_vars_cat.R +++ b/tests/testthat/test-derive_vars_cat.R @@ -330,3 +330,19 @@ test_that("derive_vars_cat Test 13: definition has wrong shape", { expect_snapshot_error(derive_vars_cat(advs, definition_wrong_shape, by_vars = exprs(VSTEST))) }) + +## Test 14: two by_vars variables ---- +test_that("derive_vars_cat Test 14: two by_vars variables", { + # Define conditions + definition <- exprs( + ~VISIT, ~VSTEST, ~condition, ~AVALCAT1, ~AVALCA1N, + "Week 24", "Height", AVAL >= 160, ">=160", 1, + "Week 24", "Height", AVAL < 160, "<160", 2, + ) + + advs_visit <- advs %>% mutate( + VISIT = "Week 24" + ) + + expect_snapshot_error(derive_vars_cat(advs_visit, definition, by_vars = exprs(VSTEST, VISIT))) +}) diff --git a/vignettes/.build.timestamp b/vignettes/.build.timestamp deleted file mode 100644 index e69de29bb..000000000 From e846b67384925c8662df0978b9901f177397ab2e Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Mon, 30 Sep 2024 07:21:32 +0000 Subject: [PATCH 81/83] lint --- R/derive_vars_cat.R | 6 ++++-- man/derive_vars_cat.Rd | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index ae4a2a24f..fd9bc589e 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -7,8 +7,10 @@ #' The `definition` object will be converted to a `tibble` using `tribble()` inside this function. #' #' Must contain: -#' - the column `condition` which will be converted to a logical expression and used on the `dataset` input. -#' - at least one additional column with the new column name and the category value(s) used by the logical expression. +#' - the column `condition` which will be converted to a logical expression and +#' will be used on the `dataset` input. +#' - at least one additional column with the new column name and +#' the category value(s) used by the logical expression. #' - the column specified in `by_vars` (if `by_vars` is specified) #' #' e.g. if `by_vars` is not specified: diff --git a/man/derive_vars_cat.Rd b/man/derive_vars_cat.Rd index 2e510f1c1..808c33392 100644 --- a/man/derive_vars_cat.Rd +++ b/man/derive_vars_cat.Rd @@ -18,8 +18,10 @@ The \code{definition} object will be converted to a \code{tibble} using \code{tr Must contain: \itemize{ -\item the column \code{condition} which will be converted to a logical expression and used on the \code{dataset} input. -\item at least one additional column with the new column name and the category value(s) used by the logical expression. +\item the column \code{condition} which will be converted to a logical expression and +will be used on the \code{dataset} input. +\item at least one additional column with the new column name and +the category value(s) used by the logical expression. \item the column specified in \code{by_vars} (if \code{by_vars} is specified) } From 5ab8252e3b05236db4bbeb6c230e0d5c0f78ee09 Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Mon, 30 Sep 2024 09:35:51 +0000 Subject: [PATCH 82/83] update to cli_warn --- R/derive_vars_cat.R | 7 +++---- tests/testthat/_snaps/derive_vars_cat.md | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index fd9bc589e..fd29532e4 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -217,10 +217,9 @@ derive_vars_cat <- function(dataset, # warn if new variables already exist if (any(new_col_names %in% names(dataset))) { - warning(paste("Column(s) in `definition` already exist in `dataset`.", - "Did you forget to specify `by_vars`,", - "or are you rerunning your code?", - sep = "\n" + cli_warn(paste("Column(s) in {.arg definition} already exist in {.arg dataset}.", + "Did you forget to specify {.arg by_vars},", + "or are you rerunning your code?" )) } diff --git a/tests/testthat/_snaps/derive_vars_cat.md b/tests/testthat/_snaps/derive_vars_cat.md index b5b2dc2df..68282aeae 100644 --- a/tests/testthat/_snaps/derive_vars_cat.md +++ b/tests/testthat/_snaps/derive_vars_cat.md @@ -1,8 +1,6 @@ # derive_vars_cat Test 3: Forgot to specify by_vars - Column(s) in `definition` already exist in `dataset`. - Did you forget to specify `by_vars`, - or are you rerunning your code? + Column(s) in `definition` already exist in `dataset`. Did you forget to specify `by_vars`, or are you rerunning your code? # derive_vars_cat Test 13: definition has wrong shape From e0a7995f9b74ef71d59356e062dc69e10148ebdc Mon Sep 17 00:00:00 2001 From: Stefan Pascal Thoma Date: Mon, 30 Sep 2024 10:17:25 +0000 Subject: [PATCH 83/83] fix style --- R/derive_vars_cat.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/derive_vars_cat.R b/R/derive_vars_cat.R index fd29532e4..7e0c12aab 100644 --- a/R/derive_vars_cat.R +++ b/R/derive_vars_cat.R @@ -217,7 +217,8 @@ derive_vars_cat <- function(dataset, # warn if new variables already exist if (any(new_col_names %in% names(dataset))) { - cli_warn(paste("Column(s) in {.arg definition} already exist in {.arg dataset}.", + cli_warn(paste( + "Column(s) in {.arg definition} already exist in {.arg dataset}.", "Did you forget to specify {.arg by_vars},", "or are you rerunning your code?" ))