Skip to content

Commit 138d1f2

Browse files
authored
Merge branch 'main' into 242_ard_tbl_11_12@main
2 parents 39b8a9c + fd83c4d commit 138d1f2

16 files changed

+595
-101
lines changed

.pre-commit-config.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# R specific hooks: https://github.com/lorenzwalthert/precommit
44
repos:
55
- repo: https://github.com/lorenzwalthert/precommit
6-
rev: v0.4.3.9001
6+
rev: v0.4.3.9003
77
hooks:
88
- id: style-files
99
args: [--style_pkg=styler, --style_fun=tidyverse_style]
@@ -50,7 +50,7 @@ repos:
5050
hooks:
5151
- id: prettier
5252
- repo: https://github.com/pre-commit/pre-commit-hooks
53-
rev: v4.6.0
53+
rev: v5.0.0
5454
hooks:
5555
- id: check-added-large-files
5656
args: ["--maxkb=200"]
@@ -76,6 +76,6 @@ repos:
7676
files: '\.Rhistory|\.RData|\.Rds|\.rds$'
7777
# `exclude: <regex>` to allow committing specific files.
7878
- repo: https://github.com/igorshubovych/markdownlint-cli
79-
rev: v0.41.0
79+
rev: v0.43.0
8080
hooks:
8181
- id: markdownlint

DESCRIPTION

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Type: Package
22
Package: cardinal
33
Title: FDA Safety Tables and Figures
4-
Version: 0.1.0.9062
5-
Date: 2024-09-19
4+
Version: 0.1.0.9063
5+
Date: 2024-12-02
66
Authors@R:
77
person("Pawel", "Rucki", , "[email protected]", role = c("aut", "cre"))
88
Description: R package with implementation of Safety Tables and Figures

NAMESPACE

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export(make_table_02_tplyr)
1212
export(make_table_03)
1313
export(make_table_04)
1414
export(make_table_05)
15+
export(make_table_05_gtsummary)
16+
export(make_table_05_rtables)
1517
export(make_table_06)
1618
export(make_table_07)
1719
export(make_table_08)

NEWS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
# cardinal 0.1.0.9062
1+
# cardinal 0.1.0.9063
22

33
* Initial release.

R/argument_convention.R

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
#' * `pct`: (optional) whether the output should be returned as percentages. Defaults to `TRUE`.
7070
#' @param saffl_var (`character`)\cr flag variable used to indicate inclusion in safety population.
7171
#' @param sex_scope (`character`)\cr Level of `SEX` to output in table.
72+
#' @param table_engine (`string`)\cr table engine used to generate the table. If `NULL`, no table is returned. If the
73+
#' given engine is not available for the table, no table is created and a warning is returned.
7274
#' @param trtedtm_var (`character`)\cr treatment end datetime variable.
7375
#' @param trtemfl_var (`character`)\cr flag variable used to identify Treatment-emergent AE.
7476
#' @param trtsdtm_var (`character`)\cr treatment start datetime variable.

R/cardinal.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ utils::globalVariables(c(
2424
"ITTFL", "PPROTFL", "RANDFL", "TRTEMFL", "TRTSDT", "USUBJID", "column", "median", "ord_layer_1", "ord_layer_2",
2525
"ord_layer_index", "param", "pct", "row_label1", "row_label2", "sd", "tbl_lbl", "value", "ENRLDT", "RANDDT",
2626
"G110", "G60", "G90", "GE120", "L60", "N", "val", "id_var", "PT_PCT", "arm", "x", "TLSTFU", "se", "lower_ci",
27-
"upper_ci", "SBP90", "DBP60", "STATUS"
27+
"upper_ci", "SBP90", "DBP60", "STATUS", "D_ANY", "D_LT1", "D_GT1", "D_GT3", "D_GT6", "D_GT12"
2828
))

R/fda-table_05.R

+218-17
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
#' @details
44
#' * `df` must contain the variables specified by `arm_var`, `saffl_var`, `id_var`, `trtsdtm_var`,
55
#' and `trtedtm_var`.
6-
#' * If specified, `alt_counts_df` must contain the variables specified by `arm_var`, `id_var` and `saffl_var`.
6+
#' * If specified, `denominator` must contain the variables specified by `arm_var`, `id_var` and `saffl_var`.
77
#' * Flag variables (i.e. `XXXFL`) are expected to have two levels: `"Y"` (true) and `"N"` (false). Missing values in
88
#' flag variables are treated as `"N"`.
9-
#' * Columns are split by arm. Overall population column is excluded by default (see `lbl_overall` argument).
10-
#' * Numbers in table "Patients Treated" section are the absolute numbers of patients and fraction of `N`.
11-
#' * All-zero rows are not removed by default (see `prune_0` argument).
12-
#' * Records with missing treatment start and/or end datetime are excluded from all calculations.
139
#'
10+
#' @inheritParams tbl_make_table_05
1411
#' @inheritParams argument_convention
15-
#' @param lbl_trtdur (`character`)\cr label for treatment duration variable.
1612
#'
17-
#' @return An `rtable` object.
13+
#' @return A `gtsummary` table and, if `return_ard = TRUE`, an ARD.
14+
#' If `return_ard = TRUE`, they will be returned as a list with named elements `table` and `ard`.
15+
#'
16+
#' @seealso [`tbl_make_table_05`]
1817
#'
1918
#' @examples
2019
#' adsl <- random.cdisc.data::cadsl
@@ -24,24 +23,54 @@
2423
#'
2524
#' @export
2625
make_table_05 <- function(df,
27-
alt_counts_df = NULL,
28-
show_colcounts = TRUE,
26+
denominator = NULL,
27+
return_ard = TRUE,
2928
arm_var = "ARM",
3029
id_var = "USUBJID",
3130
saffl_var = "SAFFL",
3231
trtsdtm_var = "TRTSDTM",
3332
trtedtm_var = "TRTEDTM",
34-
u_trtdur = "days",
35-
lbl_trtdur = paste("Duration of Treatment,", u_trtdur),
36-
lbl_overall = NULL,
37-
risk_diff = NULL,
38-
prune_0 = FALSE,
39-
annotations = NULL) {
33+
u_trtdur = "days") {
4034
assert_subset(c(id_var, arm_var, saffl_var, id_var, trtsdtm_var, trtedtm_var), names(df))
4135
assert_choice(u_trtdur, c("days", "weeks", "months", "years"))
4236
assert_flag_variables(df, saffl_var)
4337

44-
df <- df %>%
38+
ard <- ard_table_05(
39+
df = df,
40+
denominator = denominator,
41+
arm_var = arm_var,
42+
saffl_var = saffl_var,
43+
trtsdtm_var = trtsdtm_var,
44+
trtedtm_var = trtedtm_var,
45+
u_trtdur = u_trtdur
46+
)
47+
48+
tbl <- make_table_05_gtsummary(
49+
df,
50+
ard,
51+
arm_var,
52+
saffl_var,
53+
trtsdtm_var,
54+
trtedtm_var,
55+
u_trtdur
56+
)
57+
58+
if (return_ard) {
59+
return(list(table = tbl, ard = ard))
60+
} else {
61+
return(tbl)
62+
}
63+
}
64+
65+
#' Pre-Process Data for Table 5 Creation
66+
#'
67+
#' @keywords internal
68+
preproc_df_table_05 <- function(df,
69+
saffl_var = "SAFFL",
70+
trtsdtm_var = "TRTSDTM",
71+
trtedtm_var = "TRTEDTM",
72+
u_trtdur = "days") {
73+
df %>%
4574
as_tibble() %>%
4675
filter(.data[[saffl_var]] == "Y") %>%
4776
df_explicit_na() %>%
@@ -61,8 +90,180 @@ make_table_05 <- function(df,
6190
D_GT12 = (TRTDUR_MONTHS >= 12) %>% with_label(">=12 months"),
6291
DUR_LBL = "Patients Treated, by duration"
6392
)
93+
}
6494

65-
alt_counts_df <- alt_counts_df_preproc(alt_counts_df, id_var, arm_var, saffl_var)
95+
#' Make ARD: Table 5
96+
#'
97+
#' @examples
98+
#' adsl <- random.cdisc.data::cadsl
99+
#' df <- cardinal:::preproc_df_table_05(
100+
#' adsl,
101+
#' saffl_var = "SAFFL",
102+
#' trtsdtm_var = "TRTSDTM",
103+
#' trtedtm_var = "TRTEDTM",
104+
#' u_trtdur = "days"
105+
#' )
106+
#'
107+
#' ard <- cardinal:::ard_table_05(df = df)
108+
#' ard
109+
#'
110+
#' @keywords internal
111+
#' @name ard_make_table_05
112+
ard_table_05 <- function(df,
113+
denominator = NULL,
114+
arm_var = "ARM",
115+
saffl_var = "SAFFL",
116+
trtsdtm_var = "TRTSDTM",
117+
trtedtm_var = "TRTEDTM",
118+
u_trtdur = "days") {
119+
df <- preproc_df_table_05(df, saffl_var, trtsdtm_var, trtedtm_var, u_trtdur)
120+
121+
if (is.null(denominator)) {
122+
denominator <- df
123+
} else {
124+
denominator <- alt_counts_df_preproc(denominator, id_var, arm_var, saffl_var)
125+
}
126+
127+
stats_trtdur <- df |>
128+
ard_continuous(
129+
variables = "TRTDUR",
130+
by = all_of(arm_var),
131+
statistic = everything() ~ continuous_summary_fns(
132+
summaries = c("mean", "sd", "median", "min", "max", "p25", "p75"),
133+
other_stats = list(
134+
tot_exposure = \(x) sum(x),
135+
person_yrs = \(x) as.numeric(lubridate::duration(sum(x), u_trtdur), "years")
136+
)
137+
),
138+
fmt_fn = ~ list(~ \(x) round5(x, digits = 2))
139+
) |>
140+
apply_fmt_fn()
141+
142+
stats_pt_cts <- df |>
143+
group_by(!!rlang::sym(arm_var)) |>
144+
ard_dichotomous(
145+
variables = c(D_ANY, D_LT1, D_GT1, D_GT3, D_GT6, D_GT12),
146+
value = list(D_ANY = TRUE, D_LT1 = TRUE, D_GT1 = TRUE, D_GT3 = TRUE, D_GT6 = TRUE, D_GT12 = TRUE),
147+
statistic = everything() ~ c("n", "p"),
148+
denominator = denominator
149+
)
150+
151+
ard <- bind_ard(stats_trtdur, stats_pt_cts)
152+
153+
ard
154+
}
155+
156+
#' Engine-Specific Functions: Table 5
157+
#'
158+
#' The table engine used by each engine-specific function is identified by its suffix.
159+
#'
160+
#' @inheritParams argument_convention
161+
#' @param lbl_trtdur (`character`)\cr label for treatment duration variable.
162+
#'
163+
#' @details
164+
#' * Columns are split by arm. Overall population column is excluded by default (see `lbl_overall` argument).
165+
#' * Numbers in table "Patients Treated" section are the absolute numbers of patients and fraction of `N`.
166+
#' * All-zero rows are not removed by default (see `prune_0` argument).
167+
#' * Records with missing treatment start and/or end datetime are excluded from all calculations.
168+
#'
169+
#' @return
170+
#' * `make_table_05_gtsummary()` returns a `gtsummary` object.
171+
#' * `make_table_05_rtables()` returns an `rtable` object.
172+
#'
173+
#' @seealso [make_table_05()]
174+
#'
175+
#' @examples
176+
#' adsl <- random.cdisc.data::cadsl
177+
#'
178+
#' # gtsummary table --------------
179+
#' ard <- cardinal:::ard_table_05(df = adsl)
180+
#' tbl_gtsummary <- cardinal:::make_table_05_gtsummary(df = adsl, ard = ard)
181+
#' tbl_gtsummary
182+
#'
183+
#' # rtables table ----------------
184+
#' tbl_rtables <- cardinal:::make_table_05_rtables(df = adsl)
185+
#' tbl_rtables
186+
#'
187+
#' @export
188+
#' @name tbl_make_table_05
189+
make_table_05_gtsummary <- function(df,
190+
ard,
191+
arm_var = "ARM",
192+
saffl_var = "SAFFL",
193+
trtsdtm_var = "TRTSDTM",
194+
trtedtm_var = "TRTEDTM",
195+
u_trtdur = "days") {
196+
df <- preproc_df_table_05(df, saffl_var, trtsdtm_var, trtedtm_var, u_trtdur)
197+
198+
stat_fun <- function(data, ...) {
199+
dplyr::tibble(
200+
mean = mean(data$TRTDUR),
201+
sd = sd(data$TRTDUR),
202+
median = median(data$TRTDUR),
203+
min = min(data$TRTDUR),
204+
max = max(data$TRTDUR),
205+
q25 = quantile(data$TRTDUR, 0.25),
206+
q75 = quantile(data$TRTDUR, 0.75),
207+
tot_exp = sum(data$TRTDUR),
208+
tot_dur = as.numeric(lubridate::duration(sum(data$TRTDUR), u_trtdur), "years")
209+
)
210+
}
211+
212+
tbl_cts <- tbl_custom_summary(
213+
df,
214+
by = all_of(arm_var),
215+
label = list(TRTDUR = paste("Duration of Treatment,", u_trtdur)),
216+
stat_fns = everything() ~ stat_fun,
217+
statistic = ~ c("{mean} ({sd})", "{median} ({min}, {max})", "{q25} - {q75}", "{tot_exp} ({tot_dur})"),
218+
digits = ~2,
219+
type = list(TRTDUR = "continuous2"),
220+
include = TRTDUR,
221+
missing = "no"
222+
)
223+
tbl_cts$table_body$label[4:5] <- c("Interquartile range", "Total exposure (person years)")
224+
225+
tbl_cat <- tbl_ard_summary(ard, by = all_of(arm_var), include = -TRTDUR)
226+
tbl_cat$table_body <- dplyr::bind_rows(
227+
data.frame(row_type = "label", label = "Patients Treated, by duration"),
228+
tbl_cat$table_body
229+
)
230+
tbl_cat <- tbl_cat |>
231+
modify_column_indent(
232+
columns = dplyr::all_of("label"),
233+
rows = !is.na(variable),
234+
indent = 4L
235+
)
236+
tbl_cat$table_body$label[2:7] <- c(
237+
"Any duration (at least 1 dose)", "<1 month", ">=1 month", ">=3 months", ">=6 months", ">=12 months"
238+
)
239+
240+
tbl_stack(list(tbl_cts, tbl_cat), quiet = TRUE) |>
241+
modify_table_styling(
242+
columns = dplyr::all_of("label"),
243+
label = "**Parameter**"
244+
)
245+
}
246+
247+
#' @export
248+
#' @rdname tbl_make_table_05
249+
make_table_05_rtables <- function(df,
250+
alt_counts_df = NULL,
251+
show_colcounts = TRUE,
252+
arm_var = "ARM",
253+
id_var = "USUBJID",
254+
saffl_var = "SAFFL",
255+
trtsdtm_var = "TRTSDTM",
256+
trtedtm_var = "TRTEDTM",
257+
u_trtdur = "days",
258+
lbl_trtdur = paste("Duration of Treatment,", u_trtdur),
259+
lbl_overall = NULL,
260+
risk_diff = NULL,
261+
prune_0 = FALSE,
262+
annotations = NULL) {
263+
df <- preproc_df_table_05(df, saffl_var, trtsdtm_var, trtedtm_var, u_trtdur)
264+
if (!is.null(alt_counts_df)) {
265+
alt_counts_df <- alt_counts_df_preproc(alt_counts_df, id_var, arm_var, saffl_var)
266+
}
66267

67268
lyt <- basic_table_annot(show_colcounts, annotations) %>%
68269
split_cols_by_arm(arm_var, lbl_overall, risk_diff) %>%

man/ard_make_table_05.Rd

+35
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/argument_convention.Rd

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)