diff --git a/NAMESPACE b/NAMESPACE index 236fbec4be..470d47faf5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -178,6 +178,7 @@ importFrom(dplyr,full_join) importFrom(dplyr,group_by) importFrom(dplyr,group_by_at) importFrom(dplyr,if_else) +importFrom(dplyr,lag) importFrom(dplyr,mutate) importFrom(dplyr,n) importFrom(dplyr,n_distinct) diff --git a/NEWS.md b/NEWS.md index bc182ddae6..cd1d9e2dac 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,8 @@ ## Updates of Existing Functions +- `group_var` (optional) parameter is added to `derive_var_trtemfl()` to derive `TRTEMFL` for AE data if the data are collected as one episode of AE with multiple lines. (#2302) + - Templates for ADPC, ADPPK and ADPP are updated to handle urine records. (#2392) - `create_single_dose_dataset()` has been updated to error if the `lookup_table` contains duplicates. (#2247) diff --git a/R/admiral-package.R b/R/admiral-package.R index 8e9292f149..b1ab40a87e 100644 --- a/R/admiral-package.R +++ b/R/admiral-package.R @@ -6,7 +6,7 @@ #' desc distinct ends_with everything filter first full_join #' group_by group_by_at if_else mutate n n_distinct na_if pull #' rename rename_with row_number select semi_join slice starts_with -#' summarise summarise_all tibble tribble ungroup union +#' summarise summarise_all tibble tribble ungroup union lag #' @importFrom hms as_hms #' @importFrom lifecycle deprecate_warn deprecate_stop deprecated #' @importFrom lubridate %--% as_datetime ceiling_date date days duration diff --git a/R/derive_var_trtemfl.R b/R/derive_var_trtemfl.R index 5c827f13df..c12435bf44 100644 --- a/R/derive_var_trtemfl.R +++ b/R/derive_var_trtemfl.R @@ -45,12 +45,12 @@ #' #' @param initial_intensity Initial severity/intensity or toxicity #' -#' This derivation assumes AE data collection method as single record per AE -#' with "initial" and "most extreme" severity/intensity recorded separately. +#' `initial_intensity` is ignored when `group_var` is specified. #' -#' If the argument is specified, events which start before treatment start and -#' end after treatment start (or are ongoing) and worsened (i.e., the -#' intensity is greater than the initial intensity), are flagged. +#' If this argument is specified and `group_var` is `NULL`, events which start +#' before treatment start and end after treatment start (or are ongoing) and +#' worsened (i.e., the intensity is greater than the initial intensity), are +#' flagged. #' #' The values of the specified variable must be comparable with the usual #' comparison operators. I.e., if the intensity is greater than the initial @@ -72,6 +72,22 @@ #' *Permitted Values:* A symbol referring to a variable of the input dataset #' or `NULL` #' +#' @param group_var Grouping variable +#' +#' If the argument is specified, it assumes that AEs are recorded as one episode +#' of AE with multiple lines using a grouping variable. +#' +#' Events starting during treatment or before treatment and worsening afterward +#' are flagged. Once an AE record in a group is flagged, all subsequent records +#' in the treatment window are flagged regardless of severity. +#' +#' *Permitted Values:* A symbol referring to a variable of the input dataset +#' or `NULL` +#' +#' @param subject_keys Variables to uniquely identify a subject. +#' +#' A list of symbols created using `exprs()` is expected. This argument is only +#' used when `group_var` is specified. #' #' @details For the derivation of the new variable the following cases are #' considered in this order. The first case which applies, defines the value @@ -90,10 +106,15 @@ #' if `start_date` is on or after `trt_start_date` and `start_date` is on #' or before `trt_end_date` + `end_window` days, it is set to `"Y"`, #' - *event started before treatment and (possibly) worsened on treatment*: -#' - if `initial_intensity` and `intensity` is specified: if -#' `initial_intensity < intensity` and `start_date` is before -#' `trt_start_date` and `end_date` is on or after `trt_start_date` or -#' `end_date` is `NA`, it is set to `"Y"`. +#' - if `initial_intensity`, `intensity` is specified and `group_var` is not specified: +#' if `initial_intensity < intensity` and `start_date` is before `trt_start_date` +#' and `end_date` is on or after `trt_start_date` or `end_date` is `NA`, it +#' is set to `"Y"`; +#' - if `group_var` is specified: +#' if previous `intensity` < `intensity` and `start_date` is after `trt_start_date` +#' and `end_date` is on or after `trt_start_date` or `end_date` is `NA`, it +#' is set to `"Y"`; +#' #' - Otherwise it is set to `NA_character_`. #' #' @return The input dataset with the variable specified by `new_var` added @@ -109,7 +130,7 @@ #' library(dplyr, warn.conflicts = FALSE) #' library(lubridate) #' -#' adae <- expected <- tribble( +#' adae <- tribble( #' ~USUBJID, ~ASTDTM, ~AENDTM, ~AEITOXGR, ~AETOXGR, #' # before treatment #' "1", "2021-12-13T20:15", "2021-12-15T12:45", "1", "1", @@ -153,6 +174,54 @@ #' initial_intensity = AEITOXGR, #' intensity = AETOXGR #' ) %>% select(ASTDTM, AENDTM, AEITOXGR, AETOXGR, TRTEM2FL) +#' +#' adae2 <- tribble( +#' ~USUBJID, ~ASTDTM, ~AENDTM, ~AEITOXGR, ~AETOXGR, ~AEGRPID, +#' # before treatment +#' "1", "2021-12-13T20:15", "2021-12-15T12:45", "1", "1", "1", +#' "1", "2021-12-14T20:15", "2021-12-14T22:00", "1", "3", "1", +#' # starting before treatment and ending during treatment +#' "1", "2021-12-30T20:15", "2022-01-14T01:23", "3", "3", "2", +#' "1", "2022-01-05T20:00", "2022-06-01T11:00", "3", "1", "2", +#' "1", "2022-01-10T20:15", "2022-01-11T01:23", "3", "2", "2", +#' "1", "2022-01-13T20:15", "2022-03-01T01:23", "3", "1", "2", +#' # starting during treatment +#' "1", "2022-01-01T12:00", "2022-01-02T23:25", "4", "4", "3", +#' +#' # after treatment +#' "1", "2022-05-10T11:00", "2022-05-10T13:05", "2", "2", "4", +#' "1", "2022-05-10T12:00", "2022-05-10T13:05", "2", "2", "4", +#' "1", "2022-05-11T11:00", "2022-05-11T13:05", "2", "2", "4", +#' # missing dates +#' "1", "", "", "3", "4", "5", +#' "1", "2021-12-30T09:00", "", "3", "4", "5", +#' "1", "2021-12-30T11:00", "", "3", "3", "5", +#' "1", "", "2022-01-04T09:00", "3", "4", "5", +#' "1", "", "2021-12-24T19:00", "3", "4", "5", +#' "1", "", "2022-06-04T09:00", "3", "4", "5", +#' # without treatment +#' "2", "", "2021-12-03T12:00", "1", "2", "1", +#' "2", "2021-12-01T12:00", "2021-12-03T12:00", "1", "2", "2", +#' "2", "2021-12-06T18:00", "", "1", "2", "3" +#' ) %>% +#' mutate( +#' STUDYID = "ABC12345", +#' ASTDTM = ymd_hm(ASTDTM), +#' AENDTM = ymd_hm(AENDTM), +#' TRTSDTM = if_else(USUBJID == "1", ymd_hm("2022-01-01T01:01"), ymd_hms("")), +#' TRTEDTM = if_else(USUBJID == "1", ymd_hm("2022-04-30T23:59"), ymd_hms("")) +#' ) + +#' # derive TRTEMFL taking treatment end and worsening into account within a grouping variable +#' derive_var_trtemfl( +#' adae2, +#' new_var = TRTEMFL, +#' trt_end_date = TRTEDTM, +#' end_window = 10, +#' intensity = AETOXGR, +#' group_var = AEGRPID +#' ) %>% select(ASTDTM, AENDTM, AEITOXGR, AETOXGR, AEGRPID, TRTEMFL) + derive_var_trtemfl <- function(dataset, new_var = TRTEMFL, start_date = ASTDTM, @@ -162,31 +231,58 @@ derive_var_trtemfl <- function(dataset, end_window = NULL, ignore_time_for_trt_end = TRUE, initial_intensity = NULL, - intensity = NULL) { + intensity = NULL, + group_var = NULL, + subject_keys = get_admiral_option("subject_keys")) { + # Convert inputs to symbols new_var <- assert_symbol(enexpr(new_var)) start_date <- assert_symbol(enexpr(start_date)) end_date <- assert_symbol(enexpr(end_date)) trt_start_date <- assert_symbol(enexpr(trt_start_date)) - trt_end_date <- assert_symbol(enexpr(trt_end_date), optional = TRUE) + trt_end_date <- + assert_symbol(enexpr(trt_end_date), optional = TRUE) assert_integer_scalar(end_window, subset = "non-negative", optional = TRUE) assert_logical_scalar(ignore_time_for_trt_end) - initial_intensity <- assert_symbol(enexpr(initial_intensity), optional = TRUE) + initial_intensity <- + assert_symbol(enexpr(initial_intensity), optional = TRUE) intensity <- assert_symbol(enexpr(intensity), optional = TRUE) - if (is.null(initial_intensity) && !is.null(intensity)) { - cli_abort(c( - "{.arg intensity} argument was specified but not {.arg initial_intensity}", - "Either both or none of them must be specified." - )) - } - if (!is.null(initial_intensity) && is.null(intensity)) { - cli_abort(c( - "{.arg initial_intensity} argument was specified but not {.arg intensity}", - "Either both or none of them must be specified." - )) + group_var <- assert_symbol(enexpr(group_var), optional = TRUE) + + # group_var is not specified + # Check if both initial_intensity and intensity are provided + if (is.null(group_var)) { + if (is.null(initial_intensity) && !is.null(intensity)) { + cli_abort(c( + "{.arg intensity} argument was specified but not {.arg initial_intensity}", + "Either both or none of them must be specified." + )) + } + if (!is.null(initial_intensity) && is.null(intensity)) { + cli_abort(c( + "{.arg initial_intensity} argument was specified but not {.arg intensity}", + "Either both or none of them must be specified." + )) + } + # group_var is specified + } else { + if (!is.null(initial_intensity)) { + cli_warn(c( + "{.arg initial_intensity} argument is ignored when {.arg group_var} is specified", + "Please only specify one of them." + )) + } + if (is.null(subject_keys)) { + cli_abort(c( + "{.arg group_var} argument was specified but not {.arg subject_keys}", + "{.arg subject_keys} argument must be provided when {.arg group_var} is specified." + )) + } + assert_vars(subject_keys) } - assert_data_frame( - dataset, - required_vars = expr_c( + + # Assert required variables + required_vars <- + expr_c( start_date, end_date, trt_start_date, @@ -194,7 +290,12 @@ derive_var_trtemfl <- function(dataset, initial_intensity, intensity ) - ) + if (!is.null(group_var)) { + required_vars <- c(required_vars, group_var) + } + assert_data_frame(dataset, required_vars = required_vars) + + # Assert date variables assert_date_var(dataset, var = !!start_date) assert_date_var(dataset, var = !!end_date) assert_date_var(dataset, var = !!trt_start_date) @@ -202,6 +303,7 @@ derive_var_trtemfl <- function(dataset, assert_date_var(dataset, var = !!trt_end_date) } + # end window condition if (is.null(end_window)) { end_cond <- expr(TRUE) } else { @@ -212,27 +314,89 @@ derive_var_trtemfl <- function(dataset, )) } if (ignore_time_for_trt_end) { - end_cond <- expr(is.na(!!trt_end_date) | - date(!!start_date) <= date(!!trt_end_date) + days(end_window)) + end_cond <- expr( + (is.na(!!trt_end_date) | + date(!!start_date) <= date(!!trt_end_date) + days(end_window)) + ) } else { - end_cond <- expr(is.na(!!trt_end_date) | !!start_date <= !!trt_end_date + days(end_window)) + end_cond <- + expr( + (is.na(!!trt_end_date) | + !!start_date <= !!trt_end_date + days(end_window)) + ) } } + + # new_ae_cond: Y - new AE, N - AE exists before trt_start_date + new_ae_cond <- get_new_tmp_var(dataset) + if (is.null(group_var)) { + dataset <- dataset %>% + mutate( + !!new_ae_cond := if_else(!!start_date >= !!trt_start_date, "Y", "N") + ) + } else { + dataset <- dataset %>% + derive_vars_merged( + dataset_add = dataset, + by_vars = expr_c(subject_keys, group_var), + order = exprs(!!start_date), + new_vars = exprs(!!new_ae_cond := "N"), + filter_add = !!start_date < !!trt_start_date, + mode = "last" + ) %>% + mutate( + !!new_ae_cond := if_else(is.na(!!new_ae_cond), "Y", "N") + ) + } + if (is.null(intensity)) { worsening_cond <- expr(FALSE) } else { - worsening_cond <- - expr(!!start_date < !!trt_start_date & - (!!initial_intensity < !!intensity | is.na(!!initial_intensity) | is.na(!!intensity))) + if (is.null(group_var)) { + worsening_cond <- + expr( + !!start_date < !!trt_start_date & + (!!initial_intensity < !!intensity | is.na(!!initial_intensity) | + is.na(!!intensity)) + ) + } else { + prev_intensity <- get_new_tmp_var(dataset) + worsen_date <- get_new_tmp_var(dataset) + + dataset <- dataset %>% + arrange(USUBJID, !!group_var, !!start_date) %>% + group_by(USUBJID, !!group_var) %>% + mutate( + !!prev_intensity := lag(!!intensity), + !!worsen_date := + case_when( + !is.na(!!start_date) & !is.na(!!trt_start_date) & !is.na(!!prev_intensity) & + !!start_date >= !!trt_start_date & + (!!intensity > !!prev_intensity) ~ !!start_date, + TRUE ~ NA + ) + ) %>% + fill(!!worsen_date, .direction = "down") %>% + ungroup() + + worsening_cond <- expr(!is.na(!!worsen_date)) + } } - dataset %>% - mutate(!!new_var := case_when( - is.na(!!trt_start_date) ~ NA_character_, - !!end_date < !!trt_start_date ~ NA_character_, - is.na(!!start_date) ~ "Y", - !!start_date >= !!trt_start_date & !!end_cond ~ "Y", - !!worsening_cond ~ "Y" - )) + + # Derive TRTEMFL based on conditions + + dataset <- dataset %>% + mutate( + !!new_var := case_when( + is.na(!!trt_start_date) ~ NA_character_, + !!end_date < !!trt_start_date ~ NA_character_, + is.na(!!start_date) ~ "Y", + !!new_ae_cond == "Y" & !!end_cond ~ "Y", # new AE + !!worsening_cond ~ "Y" # worsened AE + ) + ) %>% + # Remove temporary variable + remove_tmp_vars() } diff --git a/R/globals.R b/R/globals.R index b498e406ab..f37003b299 100644 --- a/R/globals.R +++ b/R/globals.R @@ -129,5 +129,9 @@ globalVariables(c( "atoxgr_criteria_ctcv4", "DTYPE", "where", # this entry should be moved to @importFrom tidyselect once we use tidyselect 1.2.0 - "tmp_col_type" + "tmp_col_type", + "num_records", + "worsen_date", + "prev_intensity", + "srfl" )) diff --git a/man/derive_var_trtemfl.Rd b/man/derive_var_trtemfl.Rd index aa8ae90b46..319a6006a4 100644 --- a/man/derive_var_trtemfl.Rd +++ b/man/derive_var_trtemfl.Rd @@ -14,7 +14,9 @@ derive_var_trtemfl( end_window = NULL, ignore_time_for_trt_end = TRUE, initial_intensity = NULL, - intensity = NULL + intensity = NULL, + group_var = NULL, + subject_keys = get_admiral_option("subject_keys") ) } \arguments{ @@ -57,12 +59,12 @@ the event occurred more than \code{end_window} days after end of treatment. \item{initial_intensity}{Initial severity/intensity or toxicity -This derivation assumes AE data collection method as single record per AE -with "initial" and "most extreme" severity/intensity recorded separately. +\code{initial_intensity} is ignored when \code{group_var} is specified. -If the argument is specified, events which start before treatment start and -end after treatment start (or are ongoing) and worsened (i.e., the -intensity is greater than the initial intensity), are flagged. +If this argument is specified and \code{group_var} is \code{NULL}, events which start +before treatment start and end after treatment start (or are ongoing) and +worsened (i.e., the intensity is greater than the initial intensity), are +flagged. The values of the specified variable must be comparable with the usual comparison operators. I.e., if the intensity is greater than the initial @@ -83,6 +85,23 @@ intensity \code{initial_intensity < intensity} must evaluate to \code{TRUE}. \emph{Permitted Values:} A symbol referring to a variable of the input dataset or \code{NULL}} + +\item{group_var}{Grouping variable + +If the argument is specified, it assumes that AEs are recorded as one episode +of AE with multiple lines using a grouping variable. + +Events starting during treatment or before treatment and worsening afterward +are flagged. Once an AE record in a group is flagged, all subsequent records +in the treatment window are flagged regardless of severity. + +\emph{Permitted Values:} A symbol referring to a variable of the input dataset +or \code{NULL}} + +\item{subject_keys}{Variables to uniquely identify a subject. + +A list of symbols created using \code{exprs()} is expected. This argument is only +used when \code{group_var} is specified.} } \value{ The input dataset with the variable specified by \code{new_var} added @@ -111,10 +130,14 @@ or before \code{trt_end_date} + \code{end_window} days, it is set to \code{"Y"}, } \item \emph{event started before treatment and (possibly) worsened on treatment}: \itemize{ -\item if \code{initial_intensity} and \code{intensity} is specified: if -\code{initial_intensity < intensity} and \code{start_date} is before -\code{trt_start_date} and \code{end_date} is on or after \code{trt_start_date} or -\code{end_date} is \code{NA}, it is set to \code{"Y"}. +\item if \code{initial_intensity}, \code{intensity} is specified and \code{group_var} is not specified: +if \code{initial_intensity < intensity} and \code{start_date} is before \code{trt_start_date} +and \code{end_date} is on or after \code{trt_start_date} or \code{end_date} is \code{NA}, it +is set to \code{"Y"}; +\item if \code{group_var} is specified: +if previous \code{intensity} < \code{intensity} and \code{start_date} is after \code{trt_start_date} +and \code{end_date} is on or after \code{trt_start_date} or \code{end_date} is \code{NA}, it +is set to \code{"Y"}; } \item Otherwise it is set to \code{NA_character_}. } @@ -125,7 +148,7 @@ library(tibble) library(dplyr, warn.conflicts = FALSE) library(lubridate) -adae <- expected <- tribble( +adae <- tribble( ~USUBJID, ~ASTDTM, ~AENDTM, ~AEITOXGR, ~AETOXGR, # before treatment "1", "2021-12-13T20:15", "2021-12-15T12:45", "1", "1", @@ -169,6 +192,52 @@ derive_var_trtemfl( initial_intensity = AEITOXGR, intensity = AETOXGR ) \%>\% select(ASTDTM, AENDTM, AEITOXGR, AETOXGR, TRTEM2FL) + +adae2 <- tribble( + ~USUBJID, ~ASTDTM, ~AENDTM, ~AEITOXGR, ~AETOXGR, ~AEGRPID, + # before treatment + "1", "2021-12-13T20:15", "2021-12-15T12:45", "1", "1", "1", + "1", "2021-12-14T20:15", "2021-12-14T22:00", "1", "3", "1", + # starting before treatment and ending during treatment + "1", "2021-12-30T20:15", "2022-01-14T01:23", "3", "3", "2", + "1", "2022-01-05T20:00", "2022-06-01T11:00", "3", "1", "2", + "1", "2022-01-10T20:15", "2022-01-11T01:23", "3", "2", "2", + "1", "2022-01-13T20:15", "2022-03-01T01:23", "3", "1", "2", + # starting during treatment + "1", "2022-01-01T12:00", "2022-01-02T23:25", "4", "4", "3", + + # after treatment + "1", "2022-05-10T11:00", "2022-05-10T13:05", "2", "2", "4", + "1", "2022-05-10T12:00", "2022-05-10T13:05", "2", "2", "4", + "1", "2022-05-11T11:00", "2022-05-11T13:05", "2", "2", "4", + # missing dates + "1", "", "", "3", "4", "5", + "1", "2021-12-30T09:00", "", "3", "4", "5", + "1", "2021-12-30T11:00", "", "3", "3", "5", + "1", "", "2022-01-04T09:00", "3", "4", "5", + "1", "", "2021-12-24T19:00", "3", "4", "5", + "1", "", "2022-06-04T09:00", "3", "4", "5", + # without treatment + "2", "", "2021-12-03T12:00", "1", "2", "1", + "2", "2021-12-01T12:00", "2021-12-03T12:00", "1", "2", "2", + "2", "2021-12-06T18:00", "", "1", "2", "3" +) \%>\% + mutate( + STUDYID = "ABC12345", + ASTDTM = ymd_hm(ASTDTM), + AENDTM = ymd_hm(AENDTM), + TRTSDTM = if_else(USUBJID == "1", ymd_hm("2022-01-01T01:01"), ymd_hms("")), + TRTEDTM = if_else(USUBJID == "1", ymd_hm("2022-04-30T23:59"), ymd_hms("")) + ) +# derive TRTEMFL taking treatment end and worsening into account within a grouping variable +derive_var_trtemfl( + adae2, + new_var = TRTEMFL, + trt_end_date = TRTEDTM, + end_window = 10, + intensity = AETOXGR, + group_var = AEGRPID +) \%>\% select(ASTDTM, AENDTM, AEITOXGR, AETOXGR, AEGRPID, TRTEMFL) } \seealso{ OCCDS Functions: diff --git a/tests/testthat/_snaps/derive_var_trtemfl.md b/tests/testthat/_snaps/derive_var_trtemfl.md index fe6149e62f..2c3c488096 100644 --- a/tests/testthat/_snaps/derive_var_trtemfl.md +++ b/tests/testthat/_snaps/derive_var_trtemfl.md @@ -1,4 +1,4 @@ -# derive_var_trtemfl Test 4: error if `end_window` without `trt_end_date` +# derive_var_trtemfl Test 6: error if `end_window` without `trt_end_date` Code derive_var_trtemfl(adae, end_window = 10) @@ -7,7 +7,7 @@ ! `end_window` argument was specified but not `trt_end_date` Either both or none of them must be specified. -# derive_var_trtemfl Test 5: error if `initial_intensity` without `intensity` +# derive_var_trtemfl Test 7: error if `initial_intensity` without `intensity` Code derive_var_trtemfl(adae, initial_intensity = AEITOXGR) @@ -16,7 +16,7 @@ ! `initial_intensity` argument was specified but not `intensity` Either both or none of them must be specified. -# derive_var_trtemfl Test 6: error if `intensity` without `initial_intensity` +# derive_var_trtemfl Test 8: error if `intensity` without `initial_intensity` Code derive_var_trtemfl(adae, intensity = AETOXGR) @@ -25,3 +25,12 @@ ! `intensity` argument was specified but not `initial_intensity` Either both or none of them must be specified. +# derive_var_trtemfl Test 9: error if `intensity` without `initial_intensity` + + Code + derive_var_trtemfl(adae2, intensity = AETOXGR) + Condition + Error in `derive_var_trtemfl()`: + ! `intensity` argument was specified but not `initial_intensity` + Either both or none of them must be specified. + diff --git a/tests/testthat/test-derive_var_trtemfl.R b/tests/testthat/test-derive_var_trtemfl.R index b75b9950cb..c110da5730 100644 --- a/tests/testthat/test-derive_var_trtemfl.R +++ b/tests/testthat/test-derive_var_trtemfl.R @@ -34,6 +34,45 @@ expected <- tibble::tribble( adae <- select(expected, -starts_with("TRTEM")) +expected2 <- tribble( + ~USUBJID, ~ASTDTM, ~AENDTM, ~AEITOXGR, ~AETOXGR, ~AEGRPID, ~TRTEMFL, ~TRTEM2FL, + # before treatment + "1", "2021-12-13T20:15", "2021-12-15T12:45", "1", "1", "1", NA, NA, + "1", "2021-12-14T20:15", "2021-12-14T22:00", "1", "3", "1", NA, NA, + # starting before treatment and ending during treatment + "1", "2021-12-30T20:15", "2022-01-14T01:23", "3", "3", "2", NA, NA, + "1", "2022-01-05T20:00", "2022-06-01T11:00", "3", "1", "2", NA, NA, + "1", "2022-01-10T20:15", "2022-01-11T01:23", "3", "2", "2", "Y", "Y", + "1", "2022-01-13T20:15", "2022-03-01T01:23", "3", "1", "2", "Y", "Y", + # starting during treatment + "1", "2022-01-01T12:00", "2022-01-02T23:25", "4", "4", "3", "Y", "Y", + + # after treatment + "1", "2022-05-10T11:00", "2022-05-10T13:05", "2", "2", "4", "Y", "Y", + "1", "2022-05-10T12:00", "2022-05-10T13:05", "2", "2", "4", "Y", "Y", + "1", "2022-05-11T11:00", "2022-05-11T13:05", "2", "2", "4", NA, NA, + # missing dates + "1", "", "", "3", "4", "5", "Y", "Y", + "1", "2021-12-30T09:00", "", "3", "4", "5", NA, NA, + "1", "2021-12-30T11:00", "", "3", "3", "5", NA, NA, + "1", "", "2022-01-04T09:00", "3", "4", "5", "Y", "Y", + "1", "", "2021-12-24T19:00", "3", "4", "5", NA, NA, + "1", "", "2022-06-04T09:00", "3", "4", "5", "Y", "Y", + # without treatment + "2", "", "2021-12-03T12:00", "1", "2", "1", NA, NA, + "2", "2021-12-01T12:00", "2021-12-03T12:00", "1", "2", "2", NA, NA, + "2", "2021-12-06T18:00", "", "1", "2", "3", NA, NA +) %>% + mutate( + STUDYID = "ABC12345", + ASTDTM = lubridate::ymd_hm(ASTDTM), + AENDTM = lubridate::ymd_hm(AENDTM), + TRTSDTM = if_else(USUBJID != "2", lubridate::ymd_hm("2022-01-01T01:01"), ymd_hms("")), + TRTEDTM = if_else(USUBJID != "2", lubridate::ymd_hm("2022-04-30T23:59"), ymd_hms("")) + ) + +adae2 <- select(expected2, -starts_with("TRTEM")) + ## Test 1: end_window and worsening parameters not specfied ---- test_that("derive_var_trtemfl Test 1: end_window and worsening parameters not specfied", { expect_dfs_equal( @@ -59,8 +98,25 @@ test_that("derive_var_trtemfl Test 2: with end_window and worsening", { ) }) -## Test 3: considering trt end time ---- -test_that("derive_var_trtemfl Test 3: considering trt end time", { +## Test 3: with end_window and worsening within grouping variable---- +test_that("derive_var_trtemfl Test 3: with end_window and worsening within grouping variable", { + expect_dfs_equal( + base = select(expected2, -TRTEM2FL), + comp = derive_var_trtemfl( + adae2, + new_var = TRTEMFL, + trt_end_date = TRTEDTM, + end_window = 10, + intensity = AETOXGR, + group_var = AEGRPID + ), + keys = c("USUBJID", "ASTDTM", "AENDTM") + ) +}) + + +## Test 4: considering trt end time without grouping variable---- +test_that("derive_var_trtemfl Test 4: considering trt end time", { expect_dfs_equal( base = select(expected, -TRTEMFL, -TRTEM2FL), comp = derive_var_trtemfl( @@ -76,8 +132,25 @@ test_that("derive_var_trtemfl Test 3: considering trt end time", { ) }) -## Test 4: error if `end_window` without `trt_end_date` ---- -test_that("derive_var_trtemfl Test 4: error if `end_window` without `trt_end_date`", { +## Test 5: considering trt end time with grouping variable---- +test_that("derive_var_trtemfl Test 5: considering trt end time", { + expect_dfs_equal( + base = select(expected2, -TRTEMFL), + comp = derive_var_trtemfl( + adae2, + new_var = TRTEM2FL, + trt_end_date = TRTEDTM, + end_window = 10, + ignore_time_for_trt_end = FALSE, + intensity = AETOXGR, + group_var = AEGRPID + ), + keys = c("USUBJID", "ASTDTM", "AENDTM") + ) +}) + +## Test 6: error if `end_window` without `trt_end_date` ---- +test_that("derive_var_trtemfl Test 6: error if `end_window` without `trt_end_date`", { expect_snapshot( derive_var_trtemfl( adae, @@ -87,8 +160,8 @@ test_that("derive_var_trtemfl Test 4: error if `end_window` without `trt_end_dat ) }) -## Test 5: error if `initial_intensity` without `intensity` ---- -test_that("derive_var_trtemfl Test 5: error if `initial_intensity` without `intensity`", { +## Test 7: error if `initial_intensity` without `intensity` ---- +test_that("derive_var_trtemfl Test 7: error if `initial_intensity` without `intensity`", { expect_snapshot( derive_var_trtemfl( adae, @@ -98,8 +171,8 @@ test_that("derive_var_trtemfl Test 5: error if `initial_intensity` without `inte ) }) -## Test 6: error if `intensity` without `initial_intensity` ---- -test_that("derive_var_trtemfl Test 6: error if `intensity` without `initial_intensity`", { +## Test 8: error if `intensity` without `initial_intensity` ---- +test_that("derive_var_trtemfl Test 8: error if `intensity` without `initial_intensity`", { expect_snapshot( derive_var_trtemfl( adae, @@ -108,3 +181,26 @@ test_that("derive_var_trtemfl Test 6: error if `intensity` without `initial_inte error = TRUE ) }) + +## Test 9: error if `intensity` without `initial_intensity` ---- +test_that("derive_var_trtemfl Test 9: error if `intensity` without `initial_intensity`", { + expect_snapshot( + derive_var_trtemfl( + adae2, + intensity = AETOXGR + ), + error = TRUE + ) +}) + +## Test 10: warning if both `initial_intensity` and `group_var` are specified ---- +test_that("derive_var_trtemfl Test 9: error if `intensity` without `initial_intensity`", { + expect_warning( + derive_var_trtemfl( + adae2, + initial_intensity = AETOXGR, + group_var = AEGRPID + ), + "`initial_intensity` argument is ignored when `group_var` is specified" + ) +})