Skip to content

Commit

Permalink
update aet05 and aet05_all (#678)
Browse files Browse the repository at this point in the history
Close #665 

- Update `aet05` filter: only include "*AETTE", "*CQTTE", and "*SMQTTE".
- Update the main function (`aet05` and `aet05_all`) to let the dataset
name be exposed to users.
- Update `syn_data`.
- Update unit tests.
- Update Chevron catalog.
- Turn off partial match and catch typos.
- Update `data.R`.

---------

Signed-off-by: Liming <[email protected]>
Co-authored-by: Liming <[email protected]>
  • Loading branch information
duanx9 and clarkliming authored Nov 10, 2023
1 parent 615bc92 commit cc736c8
Show file tree
Hide file tree
Showing 14 changed files with 79 additions and 64 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
* `MNG01` plot can now be displayed without error bars and can display a continuous temporal scale on the `x` axis.
* Add a `chevron_simple` class only contain main function.
* Remove `details` argument in `script_funs`, add `name` argument.
* `AET05` preprocessing now filters on `"(AE|CQ|SMQ)TTE"` rather than `"AETTE"`.
* Rename the dataset `ADAETTE` in `syn_data` object to `ADSAFTTE`.
* Use uppercase variable names in `AET05` and `AET05_ALL`.

# chevron 0.2.4

Expand Down
41 changes: 24 additions & 17 deletions R/aet05.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#' @describeIn aet05 Main TLG function
#'
#' @inheritParams gen_args
#' @param dataset (`string`) the name of a table in the `adam_db` object.
#' @param arm_var (`string`) the arm variable used for arm splitting.
#' @param ... Further arguments passed to `tern::control_incidence_rate()`.
#'
Expand All @@ -11,29 +12,36 @@
#' * Split columns by arm, typically `ACTARM`.
#' * Split rows by parameter code.
#' * `AVAL` is patient-years at risk.
#' * `n_events` is the number of adverse events observed.
#' * `N_EVENTS` is the number of adverse events observed.
#' * The table allows confidence level to be adjusted, default is 95%.
#' * Keep zero count rows by default.
#'
#' @note
#' * `adam_db` object must contain an `adaette` table with the columns `"PARAMCD"`, `"PARAM"`, `"AVAL"`, and `"CNSR"`.
#' * `adam_db` object must contain table named as `dataset` with the columns `"PARAMCD"`, `"PARAM"`,
#' `"AVAL"`, and `"CNSR"`.
#'
#' @export
#'
aet05_main <- function(adam_db,
dataset = "adsaftte",
arm_var = "ACTARM",
lbl_overall = NULL,
...) {
assert_all_tablenames(adam_db, c("adsl", "adaette"))
assert_string(dataset)
assert_all_tablenames(adam_db, "adsl", dataset)
assert_string(arm_var)
assert_string(lbl_overall, null.ok = TRUE)
df_lbl <- paste0("adam_db$", dataset)
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor")))
assert_valid_variable(adam_db$adaette, c("USUBJID", arm_var, "PARAMCD", "PARAM"),
types = list(c("character", "factor"))
assert_valid_variable(adam_db[[dataset]], c("USUBJID", arm_var, "PARAMCD", "PARAM"),
types = list(c("character", "factor")), label = df_lbl
)
assert_valid_variable(adam_db$adaette, "AVAL", types = list("numeric"), lower = 0, na_ok = TRUE)
assert_valid_variable(adam_db$adaette, "n_events", types = list("numeric"), integerish = TRUE, lower = 0L)
assert_valid_var_pair(adam_db$adsl, adam_db$adaette, arm_var)
assert_valid_variable(adam_db[[dataset]], "AVAL", types = list("numeric"), lower = 0, na_ok = TRUE, label = df_lbl)
assert_valid_variable(adam_db[[dataset]], "N_EVENTS",
types = list("numeric"), integerish = TRUE, lower = 0L,
label = df_lbl
)
assert_valid_var_pair(adam_db$adsl, adam_db[[dataset]], arm_var)

lbl_overall <- render_safe(lbl_overall)
control <- execute_with_args(control_incidence_rate, ...)
Expand All @@ -43,11 +51,11 @@ aet05_main <- function(adam_db,
lbl_overall = lbl_overall,
param_label = "PARAM",
vars = "AVAL",
n_events = "n_events",
n_events = "N_EVENTS",
control = control
)

tbl <- build_table(lyt, adam_db$adaette, alt_counts_df = adam_db$adsl)
tbl <- build_table(lyt, adam_db[[dataset]], alt_counts_df = adam_db$adsl)

tbl
}
Expand Down Expand Up @@ -85,11 +93,11 @@ aet05_lyt <- function(arm_var,
#'
#' @export
#'
aet05_pre <- function(adam_db, ...) {
adam_db$adaette <- adam_db$adaette %>%
filter(grepl("AETTE", .data$PARAMCD)) %>%
aet05_pre <- function(adam_db, dataset = "adsaftte", ...) {
adam_db[[dataset]] <- adam_db[[dataset]] %>%
filter(grepl("(AE|CQ|SMQ)TTE", .data$PARAMCD)) %>%
mutate(
n_events = as.integer(.data$CNSR == 0)
N_EVENTS = as.integer(.data$CNSR == 0)
)

adam_db
Expand Down Expand Up @@ -120,14 +128,13 @@ aet05_post <- function(tlg, prune_0 = FALSE, ...) {
#' library(dplyr)
#' library(dunlin)
#'
#' proc_data <- log_filter(syn_data, PARAMCD == "AETTE1", "adaette")
#' proc_data <- log_filter(syn_data, PARAMCD == "AETTE1", "adsaftte")
#'
#' run(aet05, proc_data)
#'
#' run(aet05, proc_data, conf_level = 0.90, conf_type = "exact")
aet05 <- chevron_t(
main = aet05_main,
preprocess = aet05_pre,
postprocess = aet05_post,
adam_datasets = c("adsl", "adaette")
postprocess = aet05_post
)
15 changes: 7 additions & 8 deletions R/aet05_all.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
#'
#' @export
#'
aet05_all_pre <- function(adam_db, ...) {
anl_tte <- adam_db$adaette %>%
aet05_all_pre <- function(adam_db, dataset = "adsaftte", ...) {
anl_tte <- adam_db[[dataset]] %>%
filter(.data$PARAMCD == "AEREPTTE") %>%
select(all_of(c("USUBJID", "AVAL")))

adam_db$adaette <- adam_db$adaette %>%
adam_db[[dataset]] <- adam_db[[dataset]] %>%
filter(grepl("TOT", .data$PARAMCD)) %>%
mutate(
n_events = as.integer(.data$AVAL)
N_EVENTS = as.integer(.data$AVAL),
AVAL = NULL
) %>%
select(-c("AVAL")) %>%
left_join(anl_tte, by = c("USUBJID"))

adam_db
Expand All @@ -34,14 +34,13 @@ aet05_all_pre <- function(adam_db, ...) {
#' library(dplyr)
#' library(dunlin)
#'
#' proc_data <- log_filter(syn_data, PARAMCD == "AETOT1" | PARAMCD == "AEREPTTE", "adaette")
#' proc_data <- log_filter(syn_data, PARAMCD == "AETOT1" | PARAMCD == "AEREPTTE", "adsaftte")
#'
#' run(aet05_all, proc_data)
#'
#' run(aet05_all, proc_data, conf_level = 0.90, conf_type = "exact")
aet05_all <- chevron_t(
main = aet05_main,
preprocess = aet05_all_pre,
postprocess = aet05_post,
adam_datasets = c("adsl", "adaette")
postprocess = aet05_post
)
2 changes: 1 addition & 1 deletion R/data.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#' @format A named `list` of 13 `data.frames`:
#' - `adsl`
#' - `adae`
#' - `adaette`
#' - `adsaftte`
#' - `adcm`
#' - `addv`
#' - `adeg`
Expand Down
7 changes: 2 additions & 5 deletions R/kmg01.R
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,8 @@ kmg01_pre <- function(adam_db, dataset = "adtte", ...) {
#' "C: Combination" = "gray"
#' )
#'
#' syn_data2 <- log_filter(syn_data, PARAMCD == "OS", "adtte")
#' run(kmg01, syn_data2, dataset = "adtte", line_col = col)
#'
#' syn_data3 <- log_filter(syn_data, PARAMCD == "AEREPTTE", "adaette")
#' run(kmg01, syn_data3, dataset = "adaette")
#' syn_data <- log_filter(syn_data, PARAMCD == "OS", "adtte")
#' run(kmg01, syn_data, dataset = "adtte", line_col = col)
kmg01 <- chevron_g(
main = kmg01_main,
preprocess = kmg01_pre
Expand Down
3 changes: 3 additions & 0 deletions data-raw/syn_data_creation.R
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ syn_test_data <- function() {
sd$adex$ETHNIC <- factor(trimws(sd$adex$ETHNIC), levels = trimws(levels(sd$adex$ETHNIC)))
attr(sd$adex$ETHNIC, "label") <- "Ethnicity"

# useful for aet05 and aet05_all
names(sd)[names(sd) == "adaette"] <- "adsaftte"

sd
}

Expand Down
Binary file modified data/syn_data.rda
Binary file not shown.
19 changes: 14 additions & 5 deletions man/aet05.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions man/aet05_all.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 2 additions & 5 deletions man/kmg01.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/syn_data.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions tests/testthat/test-aet05.R
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
test_that("aet05 can handle NA values", {
proc_data <- syn_data
proc_data$adaette$AVAL <- NA_real_
proc_data$adaette$CNSR <- NA_real_
proc_data$adsaftte$AVAL <- NA_real_
proc_data$adsaftte$CNSR <- NA_real_

res <- expect_silent(run(aet05, proc_data))
expect_snapshot(cat(export_as_txt(res, lpp = 100)))
})

test_that("aet05 can handle some NA values", {
new_paramcd <- c(
as.character(syn_data$adaette$PARAMCD[1:4]), NA, "",
as.character(syn_data$adaette$PARAMCD[-rep(1:6)])
as.character(syn_data$adsaftte$PARAMCD[1:4]), NA, "",
as.character(syn_data$adsaftte$PARAMCD[-rep(1:6)])
)

proc_data <- syn_data

proc_data$adaette <- proc_data$adaette %>%
proc_data$adsaftte <- proc_data$adsaftte %>%
mutate(
PARAMCD = with_label(.env$new_paramcd, var_labels_for(syn_data$adaette, "PARAMCD"))
PARAMCD = with_label(.env$new_paramcd, var_labels_for(syn_data$adsaftte, "PARAMCD"))
)

res1 <- expect_silent(run(aet05, proc_data))
Expand Down
10 changes: 5 additions & 5 deletions tests/testthat/test-aet05_all.R
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
test_that("aet05_all can handle NA values", {
proc_data <- syn_data
proc_data$adaette$AVAL <- NA_real_
proc_data$adaette$CNSR <- NA_real_
proc_data$adsaftte$AVAL <- NA_real_
proc_data$adsaftte$CNSR <- NA_real_

res <- expect_silent(run(aet05_all, proc_data))
expect_snapshot(cat(export_as_txt(res, lpp = 100)))
})

test_that("aet05_all can handle some NA values", {
new_paramcd <- c(NA, "", as.character(syn_data$adaette$PARAMCD[-c(1, 2)]))
new_paramcd <- c(NA, "", as.character(syn_data$adsaftte$PARAMCD[-c(1, 2)]))

proc_data <- syn_data

proc_data$adaette <- proc_data$adaette %>%
proc_data$adsaftte <- proc_data$adsaftte %>%
mutate(
PARAMCD = with_label(.env$new_paramcd, var_labels_for(syn_data$adaette, "PARAMCD"))
PARAMCD = with_label(.env$new_paramcd, var_labels_for(syn_data$adsaftte, "PARAMCD"))
)

res1 <- expect_silent(run(aet05_all, proc_data))
Expand Down
16 changes: 7 additions & 9 deletions vignettes/chevron_catalog.rmd
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ library(chevron)

#### **1. Input dataset and dataset names**

The input dataset expected by the argument `adam_db=` in the `run(...)` function is a collection of `ADaM` datasets as a list object. Each `ADaM` dataset is expected to be an object of data frame. If the `ADaM` datasets are read in individually, user will need to combine them into a list object and provide the name of the list to `adam_db=`. Also, each element in the list are expected to have corresponding `ADaM` dataset names. Conventional `ADaM` dataset names, including `adsl`,`adex`, `adae`, `adlb`,`advs`,`adeg`,`adcm`,`admh`,`adrs`, and `adtte`, can be picked up by `chevron` with one exception. If you have a safety time-to-event dataset named as `adsaftte` following Roche standard `ADaM` convention, you will need to re-name it to `adaette` to be picked up by `chevron`.
The input dataset expected by the argument `adam_db=` in the `run(...)` function is a collection of `ADaM` datasets as a list object. Each `ADaM` dataset is expected to be an object of data frame. If the `ADaM` datasets are read in individually, user will need to combine them into a list object and provide the name of the list to `adam_db=`. Also, each element in the list are expected to have corresponding `ADaM` dataset names. Conventional `ADaM` dataset names, including `adsl`,`adex`, `adae`, `adlb`,`advs`,`adeg`,`adcm`,`admh`,`adrs`, and `adtte`, can be picked up by `chevron` with one exception.

```{r eval=FALSE}
std_data <- list(adsl = adsl, adae = adae)
Expand Down Expand Up @@ -243,12 +243,11 @@ run(aet04, syn_data, grade_groups = grade_groups, prune_0 = FALSE)
#### **1. Adverse Event Rate Adjusted for Patient-Years at Risk - First Occurrence**

1) The **`aet05`** template produces the standard adverse event rate adjusted for patient-years at risk summary considering first occurrence only.
2) Currently, the expected name for safety time-to-event dataset is `adaette` rather than `adsaftte` from other data standards.
3) By default, all `adaette` parameter codes containing the string `"TTE"` are included in the output. Users are expected to filter the parameter(s) of interest from input safety time-to-event dataset in pre-processing if needed.
4) In the input safety time-to-event dataset, in the censoring variable `CNSR` , `0` indicates the occurrence of an event of interest and `1` denotes censoring.
2) By default, all `adsaftte` parameter codes containing the string `"TTE"` are included in the output. Users are expected to filter the parameter(s) of interest from input safety time-to-event dataset in pre-processing if needed.
3) In the input safety time-to-event dataset, in the censoring variable `CNSR`, `0` indicates the occurrence of an event of interest and `1` denotes censoring.

```{r}
proc_data <- log_filter(syn_data, PARAMCD == "AETTE1", "adaette")
proc_data <- log_filter(syn_data, PARAMCD == "AETTE1", "adsaftte")
run(aet05, proc_data)
```
Expand All @@ -267,12 +266,11 @@ run(aet05, syn_data, conf_level = 0.90, conf_type = "exact")
#### **1. Adverse Event Rate Adjusted for Patient-Years at Risk - All Occurrences**

1) The **`aet05_all`** template produces the standard adverse event rate adjusted for patient-years at risk summary considering all occurrences.
2) Currently, the expected name for safety time-to-event dataset is `adaette` rather than `adsaftte` from other data standards.
3) By default, all `adaette` parameter codes containing the string `"TOT"` and the parameter code `"AEREPTTE"` are required. `"TOT"` parameters store the number of occurrences of adverse event of interests. Parameter code `"AEREPTTE"` stores the time to end of adverse event reporting period in years that contribute to the summary of "total patient-years at risk" in the output. Users are expected to filter parameters of interest from input analysis dataset in pre-processing, if needed.
4) In the input safety time-to-event dataset, in the censoring variable `CNSR` , `0` indicates the occurrence of an event of interest and `1` denotes censoring.
2) By default, all `adsaftte` parameter codes containing the string `"TOT"` and the parameter code `"AEREPTTE"` are required. `"TOT"` parameters store the number of occurrences of adverse event of interests. Parameter code `"AEREPTTE"` stores the time to end of adverse event reporting period in years that contribute to the summary of "total patient-years at risk" in the output. Users are expected to filter parameters of interest from input analysis dataset in pre-processing, if needed.
3) In the input safety time-to-event dataset, in the censoring variable `CNSR`, `0` indicates the occurrence of an event of interest and `1` denotes censoring.

```{r}
proc_data <- log_filter(syn_data, PARAMCD == "AETOT1" | PARAMCD == "AEREPTTE", "adaette")
proc_data <- log_filter(syn_data, PARAMCD == "AETOT1" | PARAMCD == "AEREPTTE", "adsaftte")
run(aet05_all, proc_data)
```
Expand Down

0 comments on commit cc736c8

Please sign in to comment.