Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

643 AEL02 [Spec Added] #655

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
869d5e4
ael02 prototype
Sep 11, 2023
7b2b2c7
add test snapshots
Sep 11, 2023
cf2f415
remove note
Sep 11, 2023
0107ea2
prototype cml02a_gl
Sep 11, 2023
4129d6e
increase test coverage
Sep 11, 2023
997dfb1
increase coverage
Sep 11, 2023
b5ee067
change title of test
Sep 11, 2023
f97a095
dsl1 and dsl2
Sep 11, 2023
4f007cc
styler
Sep 11, 2023
b06f3be
fix note
Sep 11, 2023
41207e8
ael03 and ael04
Sep 13, 2023
a4dd74e
dml01
Sep 13, 2023
72ce45b
linter
Sep 13, 2023
312f3b4
document
Sep 13, 2023
5142122
change argument
Sep 13, 2023
ff28482
dml02
Sep 13, 2023
ac59228
pdl01
Sep 13, 2023
d3209fb
update pkgdown
Sep 13, 2023
1f560a9
document
Sep 14, 2023
2ba35ab
adding missing value handling
Sep 15, 2023
572e79e
across oll key_cols
Sep 15, 2023
5f2d0f0
use render safe
Sep 18, 2023
06b9942
sorting date as first column
Sep 18, 2023
5873f39
limings suggestion
Sep 18, 2023
2b230f6
Merge branch '642-cml02a_gl-spec-added@main' into 643-ael02-spec-adde…
Sep 18, 2023
5287ec1
explicit parameter value for listings
Sep 19, 2023
f22ff47
add null report
Sep 19, 2023
a426a39
correct argument default and tests
Sep 19, 2023
e5501c4
Merge branch 'main' into 643-ael02-spec-added@main
BFalquet Sep 19, 2023
34fb219
update syn_data
Sep 20, 2023
ad9e4c9
utility function for ID
Sep 20, 2023
982d7e6
add date format
Sep 20, 2023
b57f962
use execute_with_args
Sep 20, 2023
a08dbbc
remove unused tests
Sep 20, 2023
60cdde0
simplify arguments
Sep 22, 2023
71fd248
remove default format from arguments
Sep 25, 2023
2efc471
Merge branch 'main' into 643-ael02-spec-added@main
Sep 25, 2023
cd9fe3e
fix tests
Sep 25, 2023
a54c145
correct documentation
Sep 25, 2023
918d258
add TRTDURD in syn_data
Sep 26, 2023
d799532
update dsl02 snapshot
Sep 26, 2023
453db79
update pkgdown
Sep 26, 2023
628972e
Merge remote-tracking branch 'origin/main' into 643-ael02-spec-added@…
Sep 27, 2023
d4d2f76
update linter
Sep 27, 2023
658dd60
Merge branch 'main' into 643-ael02-spec-added@main
BFalquet Oct 6, 2023
ae3bf05
update patient label
Oct 6, 2023
9f0d388
adapt dml02
Oct 6, 2023
9c0f8c3
update dml0x listings
Oct 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ Collate:
'utils.R'
'chevron_tlg-S4class.R'
'ael01_nollt.R'
'ael02.R'
'ael03.R'
'ael04.R'
'aet01.R'
'aet01_aesi.R'
'aet02.R'
Expand Down
9 changes: 9 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ export("preprocess<-")
export(ael01_nollt)
export(ael01_nollt_main)
export(ael01_nollt_pre)
export(ael02)
export(ael02_main)
export(ael02_pre)
export(ael03)
export(ael03_main)
export(ael03_pre)
export(ael04)
export(ael04_main)
export(ael04_pre)
export(aet01)
export(aet01_aesi)
export(aet01_aesi_main)
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ variables do not exist in analysis dataset.
and `legend_pos` arguments. The `table` arguments now controls the behavior of the table. The arguments `show_n` and
`show_table` are now defunct.
* Add `RMPT06` template.
* Add `AEL02`, `AEL03` and `AEL04` listing templates.

# chevron 0.2.2

Expand Down
2 changes: 1 addition & 1 deletion R/ael01_nollt.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#' @describeIn ael01_nollt Main TLG function
#'
#' @inheritParams gen_args
#' @param dataset (`character`) the name of a table in the `adam_db` object.
#' @param dataset (`string`) the name of a table in the `adam_db` object.
#' @param default_formatting (`list`) the default format of the listing columns. See [`rlistings::as_listing`].
#' @param col_formatting (`list`) the format of specific listing columns. See [`rlistings::as_listing`].
#'
Expand Down
124 changes: 124 additions & 0 deletions R/ael02.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# ael02_main ----

#' @describeIn ael02 Main TLG function
#'
#' @inheritParams gen_args
#' @param dataset (`string`) the name of a table in the `adam_db` object.
#' @param default_formatting (`list`) the default format of the listing columns. See [`rlistings::as_listing`].
#' @param col_formatting (`list`) the format of specific listing columns. See [`rlistings::as_listing`].
#'
#' @export
#'
ael02_main <- function(adam_db,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that all the listing functions should have the same main function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apart from the default arguments, it seems that all the main functions are identical

dataset = "adae",
key_cols = c("CPID", "ASR", "TRT01A"),
BFalquet marked this conversation as resolved.
Show resolved Hide resolved
disp_cols = names(adam_db[[dataset]]),
BFalquet marked this conversation as resolved.
Show resolved Hide resolved
default_formatting = list(
BFalquet marked this conversation as resolved.
Show resolved Hide resolved
all = fmt_config(align = "left"),
numeric = fmt_config(align = "center")
),
col_formatting = NULL,
unique_rows = TRUE,
Copy link
Contributor

@clarkliming clarkliming Sep 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking that these arguments are not necessary; we can remove these arguments and use

execute_with_args(
as_listing,
adam_db[[dataset]],
    key_cols = key_cols,
    disp_cols = disp_cols,
    ..., 
    default_formatting = default_formatting,
    col_formatting = col_formatting,
    unique_rows = unique_rows
)

The reason is that these arguments actually is from as_listing and we are only introducing a different default. I kind of feel like this argument is not super important and distracts users

...) {
assert_all_tablenames(adam_db, dataset)
assert_valid_variable(adam_db[[dataset]], c(key_cols, disp_cols), label = paste0("adam_db$", dataset))
assert_list(default_formatting, types = "fmt_config", names = "unique")
assert_list(col_formatting, null.ok = TRUE, types = "fmt_config", names = "unique")
assert_flag(unique_rows)

as_listing(
adam_db[[dataset]],
key_cols = key_cols,
disp_cols = disp_cols,
default_formatting = default_formatting,
col_formatting = col_formatting,
unique_rows = unique_rows
)
}

#' @describeIn ael02 Preprocessing
#'
#' @inheritParams ael02_main
#'
#' @export
#'
ael02_pre <- function(adam_db,
dataset = "adae",
...) {
adam_db[[dataset]] <- adam_db[[dataset]] %>%
filter(.data$ANL01FL == "Y") %>%
mutate(
across(
all_of(c("TRT01A", "AEDECOD", "AESEV", "AEOUT", "AEACN")),
~ reformat(.x, missing_rule)
)
) %>%
mutate(
CPID = with_label(paste(.data$SITEID, .data$SUBJID, sep = "/"), "Center/Patient ID"),
ASR = with_label(paste(.data$AGE, .data$SEX, .data$RACE, sep = "/"), "Age/Sex/Race"),
Date_First = with_label(
BFalquet marked this conversation as resolved.
Show resolved Hide resolved
toupper(format(as.Date(.data$TRTSDTM), "%d%b%Y")),
"Date of\nFirst Study\nDrug\nAdministration"
),
Duration = with_label(.data$AENDY - .data$ASTDY + 1, "AE\nDuration\nin Days"),
BFalquet marked this conversation as resolved.
Show resolved Hide resolved
Serious = with_label(ifelse(.data$AESER == "Y", "Yes", ifelse(.data$AESER == "N", "No", "")), "Serious"),
BFalquet marked this conversation as resolved.
Show resolved Hide resolved
Related = with_label(
ifelse(.data$AEREL == "Y", "Yes", ifelse(.data$AEREL == "N", "No", "")),
"Caused by\nStudy\nDrug"
),
Outcome = with_label(case_when(
AEOUT == "FATAL" ~ 1,
AEOUT == "NOT RECOVERED/NOT RESOLVED" ~ 2,
AEOUT == "RECOVERED/RESOLVED" ~ 3,
AEOUT == "RECOVERED/RESOLVED WITH SEQUELAE" ~ 4,
AEOUT == "RECOVERING/RESOLVING" ~ 5,
AEOUT == "UNKNOWN" ~ 6
), "Outcome\n(1)"),
Treated = with_label(
ifelse(.data$AECONTRT == "Y", "Yes", ifelse(.data$AECONTRT == "N", "No", "")),
"Treatment\nfor AE"
),
Action = with_label(case_when(
AEACN == "DOSE INCREASED" ~ 1,
AEACN == "DOSE NOT CHANGED" ~ 2,
AEACN == "DOSE REDUCED" | AEACN == "DOSE RATE REDUCED" ~ 3,
AEACN == "DRUG INTERRUPTED" ~ 4,
AEACN == "DRUG WITHDRAWN" ~ 5,
AEACN == "NOT APPLICABLE" | AEACN == "NOT EVALUABLE" ~ 6,
AEACN == "UNKNOWN" ~ 7
), "Action\nTaken\n(2)"),
TRT01A = with_label(.data$TRT01A, "Treatment"),
AEDECOD = with_label(reformat(as.factor(.data$AEDECOD), nocoding), "Adverse\nEvent MedDRA\nPreferred Term"),
BFalquet marked this conversation as resolved.
Show resolved Hide resolved
ASTDY = with_label(.data$ASTDY, "Study\nDay of\nOnset"),
AESEV = with_label(.data$AESEV, "Most\nExtreme\nIntensity")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for these labels, I am wondering if there are differences compared to our default labels? If the only difference is the line breaks, maybe rlistings can solve that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are a bit different (in default, ASTDY: analysis Start Relative Day, AESEV: Severity/Intensity) but we can edit the synthetic data.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to edit the synthetic data, but keep the preprocessing is fine

BFalquet marked this conversation as resolved.
Show resolved Hide resolved
) %>%
select(all_of(c(
"CPID", "ASR", "TRT01A", "AEDECOD", "Date_First", "ASTDY", "Duration",
"Serious", "AESEV", "Related", "Outcome", "Treated", "Action"
)))

adam_db
}

#' @describeIn ael02 Postprocessing
#'
#' @inheritParams gen_args
#'
ael02_post <- function(tlg, ...) {
if (nrow(tlg) == 0) tlg <- null_report

tlg
}
BFalquet marked this conversation as resolved.
Show resolved Hide resolved

#' `AEL02` Listing 1 (Default) Listing of Adverse Events.
#'
#' @include chevron_tlg-S4class.R
#' @export
#'
#' @examples
#' res <- run(ael02, syn_data)
ael02 <- chevron_l(
main = ael02_main,
preprocess = ael02_pre,
postprocess = ael02_post
)
133 changes: 133 additions & 0 deletions R/ael03.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# ael03_main ----

#' @describeIn ael03 Main TLG function
#'
#' @inheritParams gen_args
#' @param dataset (`string`) the name of a table in the `adam_db` object.
#' @param default_formatting (`list`) the default format of the listing columns. See [`rlistings::as_listing`].
#' @param col_formatting (`list`) the format of specific listing columns. See [`rlistings::as_listing`].
#'
#' @export
#'
ael03_main <- function(adam_db,
dataset = "adae",
key_cols = c("CPID", "ASR", "TRT01A"),
disp_cols = names(adam_db[[dataset]]),
default_formatting = list(
all = fmt_config(align = "left"),
numeric = fmt_config(align = "center")
),
col_formatting = NULL,
unique_rows = TRUE,
...) {
assert_all_tablenames(adam_db, dataset)
assert_valid_variable(adam_db[[dataset]], c(key_cols, disp_cols), label = paste0("adam_db$", dataset))
assert_list(default_formatting, types = "fmt_config", names = "unique")
assert_list(col_formatting, null.ok = TRUE, types = "fmt_config", names = "unique")
assert_flag(unique_rows)

as_listing(
adam_db[[dataset]],
key_cols = key_cols,
disp_cols = disp_cols,
default_formatting = default_formatting,
col_formatting = col_formatting,
unique_rows = unique_rows
)
}

#' @describeIn ael03 Preprocessing
#'
#' @inheritParams ael03_main
#'
#' @export
#'
ael03_pre <- function(adam_db,
dataset = "adae",
...) {
adam_db[[dataset]] <- adam_db[[dataset]] %>%
filter(.data$ANL01FL == "Y") %>%
filter(.data$AESER == "Y") %>%
mutate(
across(
all_of(c("TRT01A", "AEDECOD", "AESEV", "AEOUT", "AEACN")),
~ reformat(.x, missing_rule)
)
) %>%
mutate(
CPID = with_label(paste(.data$SITEID, .data$SUBJID, sep = "/"), "Center/Patient ID"),
ASR = with_label(paste(.data$AGE, .data$SEX, .data$RACE, sep = "/"), "Age/Sex/Race"),
Date_First = with_label(
toupper(format(as.Date(.data$TRTSDTM), "%d%b%Y")),
"Date of\nFirst Study\nDrug\nAdministration"
),
Duration = with_label(.data$AENDY - .data$ASTDY + 1, "AE\nDuration\nin Days"),
Related = with_label(
ifelse(.data$AEREL == "Y", "Yes", ifelse(.data$AEREL == "N", "No", "")),
"Caused by\nStudy\nDrug"
),
Outcome = with_label(case_when(
AEOUT == "FATAL" ~ 1,
AEOUT == "NOT RECOVERED/NOT RESOLVED" ~ 2,
AEOUT == "RECOVERED/RESOLVED" ~ 3,
AEOUT == "RECOVERED/RESOLVED WITH SEQUELAE" ~ 4,
AEOUT == "RECOVERING/RESOLVING" ~ 5,
AEOUT == "UNKNOWN" ~ 6
), "Outcome\n(1)"),
Treated = with_label(
ifelse(.data$AECONTRT == "Y", "Yes", ifelse(.data$AECONTRT == "N", "No", "")),
"Treatment\nfor AE"
),
Action = with_label(case_when(
AEACN == "DOSE INCREASED" ~ 1,
AEACN == "DOSE NOT CHANGED" ~ 2,
AEACN == "DOSE REDUCED" | AEACN == "DOSE RATE REDUCED" ~ 3,
AEACN == "DRUG INTERRUPTED" ~ 4,
AEACN == "DRUG WITHDRAWN" ~ 5,
AEACN == "NOT APPLICABLE" | AEACN == "NOT EVALUABLE" ~ 6,
AEACN == "UNKNOWN" ~ 7
), "Action\nTaken\n(2)"),
SERREAS = with_label(case_when(
AESDTH == "Y" ~ "1",
AESLIFE == "Y" ~ "2",
AESHOSP == "Y" ~ "3",
AESDISAB == "Y" ~ "4",
AESCONG == "Y" ~ "5",
AESMIE == "Y" ~ "6",
TRUE ~ " "
), "Reason\nClassified\nas Serious\n(3)"),
TRT01A = with_label(.data$TRT01A, "Treatment"),
AEDECOD = with_label(reformat(as.factor(.data$AEDECOD), nocoding), "Adverse\nEvent MedDRA\nPreferred Term"),
ASTDY = with_label(.data$ASTDY, "Study\nDay of\nOnset"),
AESEV = with_label(.data$AESEV, "Most\nExtreme\nIntensity")
) %>%
select(all_of(c(
"CPID", "ASR", "TRT01A", "AEDECOD", "Date_First", "ASTDY", "Duration",
"AESEV", "Related", "Outcome", "Treated", "Action", "SERREAS"
)))

adam_db
}

#' @describeIn ael03 Postprocessing
#'
#' @inheritParams gen_args
#'
ael03_post <- function(tlg, ...) {
if (nrow(tlg) == 0) tlg <- null_report

tlg
}

#' `AEL03` Listing 1 (Default) Listing of Serious Adverse Events.
#'
#' @include chevron_tlg-S4class.R
#' @export
#'
#' @examples
#' res <- run(ael03, syn_data)
ael03 <- chevron_l(
main = ael03_main,
preprocess = ael03_pre,
postprocess = ael03_post
)
97 changes: 97 additions & 0 deletions R/ael04.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# ael04_main ----

#' @describeIn ael04 Main TLG function
#'
#' @inheritParams gen_args
#' @param dataset (`string`) the name of a table in the `adam_db` object.
#' @param default_formatting (`list`) the default format of the listing columns. See [`rlistings::as_listing`].
#' @param col_formatting (`list`) the format of specific listing columns. See [`rlistings::as_listing`].
#'
#' @export
#'
ael04_main <- function(adam_db,
dataset = "adsl",
key_cols = c("CPID"),
disp_cols = names(adam_db[[dataset]]),
default_formatting = list(
all = fmt_config(align = "left"),
numeric = fmt_config(align = "center")
),
col_formatting = NULL,
unique_rows = TRUE,
...) {
assert_all_tablenames(adam_db, dataset)
assert_valid_variable(adam_db[[dataset]], c(key_cols, disp_cols), label = paste0("adam_db$", dataset))
assert_list(default_formatting, types = "fmt_config", names = "unique")
assert_list(col_formatting, null.ok = TRUE, types = "fmt_config", names = "unique")
assert_flag(unique_rows)

as_listing(
adam_db[[dataset]],
key_cols = key_cols,
disp_cols = disp_cols,
default_formatting = default_formatting,
col_formatting = col_formatting,
unique_rows = unique_rows
)
}

#' @describeIn ael04 Preprocessing
#'
#' @inheritParams ael04_main
#'
#' @export
#'
ael04_pre <- function(adam_db,
dataset = "adsl",
...) {
adam_db[[dataset]] <- adam_db[[dataset]] %>%
filter(!is.na(.data$DTHADY)) %>%
mutate(
across(
all_of(c("TRT01A", "DTHCAUS", "ADTHAUT")),
~ reformat(.x, missing_rule)
)
) %>%
mutate(
CPID = with_label(paste(.data$SITEID, .data$SUBJID, sep = "/"), "Center/Patient ID"),
ASR = with_label(paste(.data$AGE, .data$SEX, .data$RACE, sep = "/"), "Age/Sex/Race"),
Date_First = with_label(
toupper(format(as.Date(.data$TRTSDTM), "%d%b%Y")),
"Date of\nFirst Study\nDrug\nAdministration"
),
TRT01A = with_label(.data$TRT01A, "Treatment"),
EOSDY = with_label(.data$EOSDY, "Day of Last\nStudy Drug\nAdministration"),
DTHADY = with_label(.data$DTHADY, "Day of\nDeath"),
DTHCAUS = with_label(.data$DTHCAUS, "Cause of Death"),
ADTHAUT = with_label(.data$ADTHAUT, "Autopsy\nPerformed?")
) %>%
select(all_of(c(
BFalquet marked this conversation as resolved.
Show resolved Hide resolved
"CPID", "ASR", "TRT01A", "Date_First", "EOSDY", "DTHADY", "DTHCAUS", "ADTHAUT"
)))

adam_db
}

#' @describeIn ael04 Postprocessing
#'
#' @inheritParams gen_args
#'
ael04_post <- function(tlg, ...) {
if (nrow(tlg) == 0) tlg <- null_report

tlg
}

#' `AEL04` Listing 1 (Default) Listing of Patient Deaths.
#'
#' @include chevron_tlg-S4class.R
#' @export
#'
#' @examples
#' res <- run(ael04, syn_data)
ael04 <- chevron_l(
main = ael04_main,
preprocess = ael04_pre,
postprocess = ael04_post
)
Loading