1 |
# as we use NSE |
|
2 |
globalVariables(c(".", ":=")) |
|
3 | ||
4 |
#' Retrieve labels for certain variables |
|
5 |
#' |
|
6 |
#' @param df (`data.frame`) containing columns with label attribute. |
|
7 |
#' @param vars (`character`) variable names in `df`. |
|
8 |
#' @returns a `character` with replaced placeholders and a `label` attribute. |
|
9 |
#' |
|
10 |
#' @details |
|
11 |
#' The labels will be returned if the column has `label` attribute, otherwise the column name will be returned. |
|
12 |
#' Any values between brackets {} will be replaced with `dunlin::render_safe`. |
|
13 |
#' |
|
14 |
#' @export |
|
15 |
var_labels_for <- function(df, vars) { |
|
16 | 333x |
assert_names(colnames(df), must.include = vars, what = "colnames") |
17 | 333x |
render_safe(unname(formatters::var_labels(df, fill = TRUE)[vars])) |
18 |
} |
|
19 | ||
20 |
#' Prune table up to an `ElementaryTable` |
|
21 |
#' |
|
22 |
#' Avoid returning `NULL` when the `table` is empty. |
|
23 |
#' |
|
24 |
#' @param tlg (`TableTree`) object. |
|
25 |
#' @returns pruned `TableTree`. |
|
26 |
smart_prune <- function(tlg) { |
|
27 | 103x |
res <- prune_table(tlg) |
28 | ||
29 | 103x |
if (is.null(res)) { |
30 | 21x |
res <- build_table(rtables::basic_table(), df = data.frame()) |
31 | 21x |
col_info(res) <- col_info(tlg) |
32 |
} |
|
33 | ||
34 | 103x |
res |
35 |
} |
|
36 | ||
37 |
#' Standard Main Listing Function |
|
38 |
#' |
|
39 |
#' @inheritParams gen_args |
|
40 |
#' @param ... additional arguments passed to [`rlistings::as_listing`]. |
|
41 |
#' @returns the main function returns an `rlistings` or a `list` object. |
|
42 |
#' |
|
43 |
#' @keywords internal |
|
44 |
std_listing <- function(adam_db, |
|
45 |
dataset, |
|
46 |
key_cols, |
|
47 |
disp_cols, |
|
48 |
split_into_pages_by_var, |
|
49 |
unique_rows = FALSE, |
|
50 |
...) { |
|
51 | 4x |
assert_all_tablenames(adam_db, dataset) |
52 | 4x |
assert_valid_variable(adam_db[[dataset]], c(key_cols, disp_cols), label = paste0("adam_db$", dataset)) |
53 | ||
54 | 4x |
execute_with_args( |
55 | 4x |
as_listing, |
56 | 4x |
df = adam_db[[dataset]], |
57 | 4x |
key_cols = key_cols, |
58 | 4x |
disp_cols = disp_cols, |
59 | 4x |
split_into_pages_by_var = split_into_pages_by_var, |
60 |
..., |
|
61 | 4x |
default_formatting = listing_format_chevron(), |
62 | 4x |
unique_rows = unique_rows |
63 |
) |
|
64 |
} |
|
65 | ||
66 |
# Special formats ---- |
|
67 | ||
68 |
#' Decimal formatting |
|
69 |
#' |
|
70 |
#' @param digits (`integer`) number of digits. |
|
71 |
#' @param format (`string`) describing how the numbers should be formatted following the `sprintf` syntax. |
|
72 |
#' @param ne (`string`) that should replace actual value. If `NULL`, no replacement is performed. |
|
73 |
#' |
|
74 |
#' @returns `function` formatting numbers with the defined format. |
|
75 |
#' |
|
76 |
#' @export |
|
77 |
#' |
|
78 |
#' @examples |
|
79 |
#' fun <- h_format_dec(c(1, 1), "%s - %s") |
|
80 |
#' fun(c(123, 567.89)) |
|
81 |
h_format_dec <- function(digits, format, ne = NULL) { |
|
82 | 9149x |
assert_integerish(digits, lower = 0) |
83 | 9149x |
assert_string(format) |
84 | 9149x |
assert_string(ne, null.ok = TRUE) |
85 | 9149x |
if (any(is.na(digits))) { |
86 | 697x |
function(x, ...) { |
87 |
"" |
|
88 |
} |
|
89 |
} else { |
|
90 | 8452x |
if (!is.null(ne)) { |
91 | 4116x |
ret <- function(x, ...) { |
92 | 4116x |
do_call(sprintf, c(list(fmt = format), rep(ne, length(digits)))) |
93 |
} |
|
94 | 4116x |
return(ret) |
95 |
} |
|
96 | 4336x |
digit_string <- paste0("%", ifelse(is.na(digits), "", paste0(".", digits)), "f") |
97 | 4336x |
new_format <- do_call(sprintf, c(list(fmt = format), digit_string)) |
98 | 4336x |
formatters::sprintf_format(new_format) |
99 |
} |
|
100 |
} |
|
101 | ||
102 |
#' Fuse list elements |
|
103 |
#' |
|
104 |
#' @param x (`list`) to fuse. |
|
105 |
#' @param y (`list`) to fuse. Elements with names already existing in `x` are discarded. |
|
106 |
#' |
|
107 |
#' @keywords internal |
|
108 |
fuse_sequentially <- function(x, y) { |
|
109 | 6x |
if (missing(y)) { |
110 | 1x |
return(x) |
111 |
} |
|
112 | ||
113 | 5x |
names_x <- names(x) |
114 | 5x |
sel_names_y <- setdiff(names(y), names_x) |
115 | ||
116 | 5x |
c(x, y[sel_names_y]) |
117 |
} |
|
118 | ||
119 |
# lvl ---- |
|
120 | ||
121 |
#' @export |
|
122 |
droplevels.character <- function(x, ...) { |
|
123 | 1x |
x |
124 |
} |
|
125 | ||
126 |
#' Obtain levels from vector |
|
127 |
#' |
|
128 |
#' @param x (`character`) or (`factor`) object to obtain levels. |
|
129 |
#' @returns `character` with unique values. |
|
130 |
#' @details |
|
131 |
#' For factors, the levels will be returned. For characters, the sorted unique values will be returned. |
|
132 |
#' |
|
133 |
#' @export |
|
134 |
lvls <- function(x) { |
|
135 | 402x |
UseMethod("lvls") |
136 |
} |
|
137 |
#' @export |
|
138 |
lvls.default <- function(x) { |
|
139 | 1x |
NULL |
140 |
} |
|
141 |
#' @export |
|
142 |
lvls.character <- function(x) { |
|
143 | 8x |
sort(unique(x)) |
144 |
} |
|
145 |
#' @export |
|
146 |
lvls.factor <- function(x) { |
|
147 | 393x |
levels(x) |
148 |
} |
|
149 | ||
150 |
#' @keywords internal |
|
151 |
quote_str <- function(x) { |
|
152 | 14x |
assert_string(x) |
153 | 13x |
paste0("`", x, "`") |
154 |
} |
|
155 | ||
156 |
#' @keywords internal |
|
157 |
modify_default_args <- function(fun, ...) { |
|
158 | 1x |
ret <- fun |
159 | 1x |
formals(ret) <- utils::modifyList(formals(fun), list(...), keep.null = TRUE) |
160 | 1x |
return(ret) |
161 |
} |
|
162 | ||
163 |
#' Execute function with given arguments |
|
164 |
#' |
|
165 |
#' @details If the function has `...`, this function will not pass other arguments to `...`. |
|
166 |
#' Only named arguments are passed. |
|
167 |
#' |
|
168 |
#' @keywords internal |
|
169 |
execute_with_args <- function(fun, ...) { |
|
170 | 125x |
args <- list(...) |
171 | 125x |
do_call(fun, args[intersect(names(args), formalArgs(fun))]) |
172 |
} |
|
173 | ||
174 |
#' Execute a function call |
|
175 |
#' |
|
176 |
#' @keywords internal |
|
177 |
do_call <- function(what, args) { |
|
178 | 9257x |
arg_names <- names(args) |
179 | 9257x |
if (is.null(arg_names)) { |
180 | 117x |
arg_names <- sprintf("var_%s", seq_along(args)) |
181 | 9140x |
} else if (any(arg_names == "")) { |
182 | 8608x |
arg_names_random <- sprintf("var_%s", seq_along(args)) |
183 | 8608x |
arg_names[arg_names == ""] <- arg_names_random[arg_names == ""] |
184 |
} |
|
185 | 9257x |
args_env <- as.environment(setNames(args, arg_names)) |
186 | 9257x |
parent.env(args_env) <- parent.frame() |
187 | 9257x |
new_args <- lapply(arg_names, as.symbol) |
188 | 9257x |
names(new_args) <- names(args) |
189 | 9257x |
do.call(what, new_args, envir = args_env) |
190 |
} |
|
191 | ||
192 |
#' Modify character |
|
193 |
#' |
|
194 |
#' @keywords internal |
|
195 |
modify_character <- function(x, y) { |
|
196 | 34x |
assert_character(x, names = "unique", null.ok = TRUE) |
197 | 34x |
assert_character(y, names = "unique", null.ok = TRUE) |
198 | 34x |
c(y, x)[unique(c(names(x), names(y)))] |
199 |
} |
|
200 | ||
201 |
#' Expand list to each split |
|
202 |
#' @keywords internal |
|
203 |
expand_list <- function(lst, split) { |
|
204 | 26x |
assert_list(lst, names = "unique") |
205 | 26x |
assert_character(split) |
206 | 26x |
if ("all" %in% names(lst)) { |
207 | 16x |
lst <- lapply( |
208 | 16x |
setNames(split, split), |
209 | 16x |
function(x) { |
210 | 32x |
modify_character(lst$all, lst[[x]]) |
211 |
} |
|
212 |
) |
|
213 |
} |
|
214 | 26x |
lst |
215 |
} |
|
216 | ||
217 |
#' Helper function to convert to months if needed |
|
218 |
#' |
|
219 |
#' @param x (`numeric`) time. |
|
220 |
#' @param unit (`character`) or (`factor`) time unit. |
|
221 |
#' |
|
222 |
#' @returns A `numeric` vector with the time in months. |
|
223 |
#' |
|
224 |
#' @export |
|
225 |
convert_to_month <- function(x, unit) { |
|
226 | 19x |
assert_multi_class(unit, c("character", "factor")) |
227 | 19x |
assert_numeric(x, len = length(unit)) |
228 | ||
229 | 19x |
unit <- toupper(unit) |
230 | 19x |
diff <- setdiff(unique(unit), c("DAYS", "MONTHS", "YEARS")) |
231 | 19x |
if (length(diff) > 0) { |
232 | 1x |
rlang::warn( |
233 | 1x |
paste0( |
234 | 1x |
"Time unit ", toString(diff), " not covered. No unit conversion applied." |
235 |
) |
|
236 |
) |
|
237 |
} |
|
238 | ||
239 | 19x |
case_when( |
240 | 19x |
unit == "DAYS" ~ x / 30.4375, |
241 | 19x |
unit == "MONTHS" ~ x, |
242 | 19x |
unit == "YEARS" ~ x * 12, |
243 | 19x |
TRUE ~ x |
244 |
) |
|
245 |
} |
|
246 | ||
247 |
#' Theme for Chevron Plot |
|
248 |
#' |
|
249 |
#' @param grid_y (`flag`) should horizontal grid be displayed. |
|
250 |
#' @param grid_x (`flag`) should vertical grid be displayed. |
|
251 |
#' @param legend_position (`string`) the position of the legend. |
|
252 |
#' @param text_axis_x_rot (`numeric`) the x axis text rotation angle. |
|
253 |
#' |
|
254 |
#' @returns a `theme` object. |
|
255 |
#' |
|
256 |
#' @export |
|
257 |
#' |
|
258 |
gg_theme_chevron <- function(grid_y = TRUE, |
|
259 |
grid_x = FALSE, |
|
260 |
legend_position = "top", |
|
261 |
text_axis_x_rot = 45) { |
|
262 | 14x |
assert_flag(grid_y) |
263 | 14x |
assert_flag(grid_x) |
264 | 14x |
assert_choice(legend_position, c("top", "bottom", "right", "left")) |
265 | 14x |
assert_numeric(text_axis_x_rot, len = 1, lower = -90, upper = 90) |
266 | ||
267 | 14x |
ggtheme <- ggplot2::theme_bw() + |
268 | 14x |
ggplot2::theme(legend.position = legend_position) + |
269 | 14x |
ggplot2::theme(axis.title.x = ggplot2::element_blank()) |
270 | ||
271 | 14x |
ggtheme <- if (!grid_x) { |
272 | 14x |
ggtheme + ggplot2::theme( |
273 | 14x |
panel.grid.major.x = ggplot2::element_blank(), |
274 | 14x |
panel.grid.minor.x = ggplot2::element_blank() |
275 |
) |
|
276 |
} else { |
|
277 | ! |
ggtheme + ggplot2::theme( |
278 | ! |
panel.grid.major.x = ggplot2::element_line(linewidth = ggplot2::rel(0.5)), |
279 | ! |
panel.grid.minor.x = ggplot2::element_blank() |
280 |
) |
|
281 |
} |
|
282 | ||
283 | 14x |
ggtheme <- if (!grid_y) { |
284 | ! |
ggtheme + ggplot2::theme( |
285 | ! |
panel.grid.minor.y = ggplot2::element_blank(), |
286 | ! |
panel.grid.major.y = ggplot2::element_blank() |
287 |
) |
|
288 |
} else { |
|
289 | 14x |
ggtheme + ggplot2::theme( |
290 | 14x |
panel.grid.minor.y = ggplot2::element_blank(), |
291 | 14x |
panel.grid.major.y = ggplot2::element_line(linewidth = ggplot2::rel(0.5)) |
292 |
) |
|
293 |
} |
|
294 | ||
295 | 14x |
ggtheme <- ggtheme + ggplot2::theme( |
296 | 14x |
axis.text.x = ggplot2::element_text( |
297 | 14x |
angle = text_axis_x_rot, |
298 | 14x |
hjust = get_x_hjust(text_axis_x_rot), |
299 | 14x |
vjust = get_x_vjust(text_axis_x_rot) |
300 |
) |
|
301 |
) |
|
302 | ||
303 | 14x |
ggtheme |
304 |
} |
|
305 | ||
306 |
#' Get a harmonious value of horizontal justification for x axis |
|
307 |
#' |
|
308 |
#' @param x (`numeric`) angle between -90 and 90 degree. |
|
309 |
#' @keywords internal |
|
310 |
get_x_hjust <- function(x) { |
|
311 | 14x |
assert_numeric(x, upper = 90, lower = -90, len = 1) |
312 | ||
313 | 14x |
if (x == 0) { |
314 | ! |
0.5 |
315 | 14x |
} else if (x > 0) { |
316 | 14x |
1 |
317 |
} else { |
|
318 | ! |
0 |
319 |
} |
|
320 |
} |
|
321 | ||
322 |
#' Get a harmonious value of vertical justification for x axis |
|
323 |
#' |
|
324 |
#' @param x (`numeric`) angle between -90 and 90 degree. |
|
325 |
#' @keywords internal |
|
326 |
get_x_vjust <- function(x) { |
|
327 | 14x |
assert_numeric(x, upper = 90, lower = -90, len = 1) |
328 | ||
329 | 14x |
if (x == 0) { |
330 | ! |
0 |
331 | 14x |
} else if (abs(x) == 90) { |
332 | ! |
0.5 |
333 |
} else { |
|
334 | 14x |
1 |
335 |
} |
|
336 |
} |
|
337 | ||
338 |
#' Get Section dividers |
|
339 |
#' @export |
|
340 |
#' @returns (`character`) value with section dividers at corresponding section. |
|
341 |
get_section_div <- function() { |
|
342 | 26x |
x <- getOption("chevron.section_div", integer(0)) |
343 | 26x |
if (!test_integerish(x)) { |
344 | ! |
ret <- NA_character_ |
345 |
} else { |
|
346 | 26x |
ret <- rep(NA_character_, max(x, 0)) |
347 | 26x |
ret[x] <- "" |
348 |
} |
|
349 | 26x |
ret |
350 |
} |
|
351 | ||
352 |
#' Set Section Dividers |
|
353 |
#' @export |
|
354 |
#' @param x (`integerish`) value of at which the section divider should be added. |
|
355 |
#' @details Section dividers are empty lines between sections in tables. |
|
356 |
#' E.g. if 1 is used then for the first row split an empty line is added. |
|
357 |
#' Currently it only works for `aet02`, `cmt01a` and `mht01` template. |
|
358 |
#' @returns invisible `NULL`. Set the `chevron.section_div` option. |
|
359 |
#' @export |
|
360 |
set_section_div <- function(x) { |
|
361 | 4x |
assert_integerish(x, min.len = 0L, any.missing = FALSE, lower = 1L) |
362 | 2x |
options("chevron.section_div" = x) |
363 | 2x |
invisible() |
364 |
} |
|
365 | ||
366 |
#' @keywords internal |
|
367 |
to_list <- function(x) { |
|
368 | 24x |
if (length(x) == 1L) { |
369 | 16x |
return(x) |
370 |
} |
|
371 | 8x |
x <- as.list(x) |
372 | 8x |
lapply(x, to_list) |
373 |
} |
|
374 | ||
375 |
# Deprecated functions ---- |
|
376 | ||
377 |
#' List of `grob` object |
|
378 |
#' |
|
379 |
#' `r lifecycle::badge("deprecated")` |
|
380 |
#' |
|
381 |
#' @param ... (`grob`) objects. |
|
382 |
#' @returns a `grob_list` object. |
|
383 |
#' @export |
|
384 |
grob_list <- function(...) { |
|
385 | 1x |
lifecycle::deprecate_warn("0.2.5.9009", "grob_list()", "list()") |
386 | 1x |
list(...) |
387 |
} |
|
388 | ||
389 |
#' List of `gg` object |
|
390 |
#' |
|
391 |
#' `r lifecycle::badge("deprecated")` |
|
392 |
#' |
|
393 |
#' @param ... (`ggplot`) objects. |
|
394 |
#' @returns a `gg_list` object. |
|
395 |
#' @export |
|
396 |
gg_list <- function(...) { |
|
397 | 1x |
lifecycle::deprecate_warn("0.2.5.9009", "gg_list()", "list()") |
398 | 1x |
list(...) |
399 |
} |
|
400 | ||
401 | ||
402 |
#' Format for Chevron Listings |
|
403 |
#' |
|
404 |
#' @return a `list` of `fmt_config`. |
|
405 |
#' |
|
406 |
listing_format_chevron <- function() { |
|
407 | 17x |
list( |
408 | 17x |
all = fmt_config(align = "left"), |
409 | 17x |
numeric = fmt_config(align = "center"), |
410 | 17x |
Date = fmt_config(format = format_date(), align = "left"), |
411 | 17x |
POSIXct = fmt_config(format = format_date(), align = "left"), |
412 | 17x |
POSIXt = fmt_config(format = format_date(), align = "left") |
413 |
) |
|
414 |
} |
|
415 | ||
416 |
#' Formatting of date |
|
417 |
#' |
|
418 |
#' @param date_format (`string`) the output format. |
|
419 |
#' |
|
420 |
#' @return a `function` converting a date into `string`. |
|
421 |
#' |
|
422 |
#' @note The date is extracted at the location of the measure, not at the location of the system. |
|
423 |
#' |
|
424 |
#' @export |
|
425 |
#' @examples |
|
426 |
#' format_date("%d%b%Y")(as.Date("2021-01-01")) |
|
427 |
#' if ("NZ" %in% OlsonNames()) { |
|
428 |
#' format_date("%d%b%Y")(as.POSIXct("2021-01-01 00:00:01", tz = "NZ")) |
|
429 |
#' } |
|
430 |
#' if ("US/Pacific" %in% OlsonNames()) { |
|
431 |
#' format_date("%d%b%Y")(as.POSIXct("2021-01-01 00:00:01", tz = "US/Pacific")) |
|
432 |
#' } |
|
433 |
format_date <- function(date_format = "%d%b%Y") { |
|
434 | 55x |
function(x, ...) { |
435 | 1324x |
toupper( |
436 | 1324x |
format( |
437 |
# Extract the date at the location of the measure, not at the location of the system. |
|
438 | 1324x |
lubridate::force_tz(x, tzone = "UTC"), |
439 | 1324x |
date_format, |
440 | 1324x |
tz = "UTC" |
441 |
) |
|
442 |
) |
|
443 |
} |
|
444 |
} |
|
445 | ||
446 |
# listing_id ---- |
|
447 | ||
448 |
#' Concatenate Site and Subject ID |
|
449 |
#' |
|
450 |
#' @param site (`string`) |
|
451 |
#' @param subject (`string`) |
|
452 |
#' @param sep (`string`) |
|
453 |
#' |
|
454 |
#' @note the `{Patient_label}` whisker placeholder will be used in the label. |
|
455 |
#' |
|
456 |
#' @export |
|
457 |
#' @examples |
|
458 |
#' create_id_listings("BRA-1", "xxx-1234") |
|
459 |
create_id_listings <- function(site, subject, sep = "/") { |
|
460 | 6x |
assert_character(site) |
461 | 6x |
assert_character(subject) |
462 | 6x |
assert_string(sep) |
463 | ||
464 | 6x |
subject_id <- stringr::str_split_i(subject, pattern = "-", i = -1) |
465 | ||
466 | 6x |
with_label(paste(site, subject_id, sep = sep), render_safe("Center/{Patient_label} ID")) |
467 |
} |
1 |
# kmg01 ---- |
|
2 | ||
3 |
#' @describeIn kmg01 Main TLG Function |
|
4 |
#' |
|
5 |
#' @details |
|
6 |
#' * No overall value. |
|
7 |
#' |
|
8 |
#' @inheritParams gen_args |
|
9 |
#' @param dataset (`string`) the name of a table in the `adam_db` object. |
|
10 |
#' @param strata (`character`) the variable name of stratification variables. |
|
11 |
#' @param strat (`character`) `r lifecycle::badge("deprecated")`; for backwards compatibility only. |
|
12 |
#' Use `strata` instead. |
|
13 |
#' @param ... Further arguments passed to `g_km` and `control_coxph`. For details, see |
|
14 |
#' the documentation in `tern`. |
|
15 |
#' Commonly used arguments include `col`, `pval_method`, `ties`, `conf_level`, `conf_type`, |
|
16 |
#' `annot_coxph`, `annot_stats`, etc. |
|
17 |
#' @returns the main function returns a `gTree` object. |
|
18 |
#' |
|
19 |
#' @note |
|
20 |
#' * `adam_db` object must contain the table specified by `dataset` with the columns specified by `arm_var`. |
|
21 |
#' |
|
22 |
#' @returns a `gTree` object. |
|
23 |
#' @export |
|
24 |
kmg01_main <- function(adam_db, |
|
25 |
dataset = "adtte", |
|
26 |
arm_var = "ARM", |
|
27 |
strata = NULL, |
|
28 |
strat = lifecycle::deprecated(), |
|
29 |
...) { |
|
30 | 1x |
assert_all_tablenames(adam_db, c("adsl", dataset)) |
31 | 1x |
df_lbl <- paste0("adam_db$", dataset) |
32 | 1x |
assert_valid_variable(adam_db[[dataset]], "AVAL", types = list("numeric"), lower = 0, label = df_lbl) |
33 | 1x |
assert_valid_variable(adam_db[[dataset]], "IS_EVENT", types = list("logical"), label = df_lbl) |
34 | 1x |
if (lifecycle::is_present(strat)) { |
35 | ! |
lifecycle::deprecate_warn( |
36 | ! |
when = "0.2.6", |
37 | ! |
what = "kmg01_main(strat)", |
38 | ! |
with = "km01_main(strata)" |
39 |
) |
|
40 | ! |
strata <- strat |
41 |
} |
|
42 | 1x |
assert_valid_variable(adam_db[[dataset]], strata, types = list(c("character", "factor")), label = df_lbl) |
43 | 1x |
assert_valid_variable( |
44 | 1x |
adam_db[[dataset]], |
45 | 1x |
c("PARAMCD", arm_var), |
46 | 1x |
types = list(c("character", "factor")), |
47 | 1x |
na_ok = FALSE, |
48 | 1x |
label = df_lbl |
49 |
) |
|
50 | 1x |
assert_single_value(adam_db[[dataset]]$PARAMCD, label = paste0(df_lbl, "$PARAMCD")) |
51 | 1x |
assert_valid_variable(adam_db[[dataset]], "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
52 | 1x |
variables <- list(tte = "AVAL", is_event = "IS_EVENT", arm = arm_var, strata = strata) |
53 | 1x |
control_cox <- execute_with_args(control_coxph, ...) |
54 | 1x |
control_surv <- execute_with_args(control_surv_timepoint, ...) |
55 | 1x |
execute_with_args( |
56 | 1x |
g_km, |
57 | 1x |
df = adam_db[[dataset]], |
58 | 1x |
variables = variables, |
59 | 1x |
control_surv = control_surv, |
60 | 1x |
control_coxph_pw = control_cox, |
61 |
... |
|
62 |
) |
|
63 |
} |
|
64 | ||
65 |
#' @describeIn kmg01 Preprocessing |
|
66 |
#' |
|
67 |
#' @inheritParams kmg01_main |
|
68 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
69 |
#' @export |
|
70 |
kmg01_pre <- function(adam_db, dataset = "adtte", ...) { |
|
71 | 1x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
72 | 1x |
mutate(IS_EVENT = .data$CNSR == 0) |
73 | ||
74 | 1x |
adam_db |
75 |
} |
|
76 | ||
77 |
# `kmg01` Pipeline ---- |
|
78 | ||
79 |
#' `KMG01` Kaplan-Meier Plot 1. |
|
80 |
#' |
|
81 |
#' @include chevron_tlg-S4class.R |
|
82 |
#' @export |
|
83 |
#' |
|
84 |
#' @examples |
|
85 |
#' library(dplyr) |
|
86 |
#' library(dunlin) |
|
87 |
#' |
|
88 |
#' col <- c( |
|
89 |
#' "A: Drug X" = "black", |
|
90 |
#' "B: Placebo" = "blue", |
|
91 |
#' "C: Combination" = "gray" |
|
92 |
#' ) |
|
93 |
#' |
|
94 |
#' pre_data <- log_filter(syn_data, PARAMCD == "OS", "adtte") |
|
95 |
#' run(kmg01, pre_data, dataset = "adtte", col = col) |
|
96 |
kmg01 <- chevron_g( |
|
97 |
main = kmg01_main, |
|
98 |
preprocess = kmg01_pre |
|
99 |
) |
1 |
# rspt01 ---- |
|
2 | ||
3 |
#' @describeIn rspt01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param dataset (`string`) the name of a table in the `adam_db` object. |
|
7 |
#' @param ref_group (`string`) The name of the reference group, the value should |
|
8 |
#' be identical to the values in `arm_var`, if not specified, it will by default |
|
9 |
#' use the first level or value of `arm_var`. |
|
10 |
#' @param odds_ratio (`flag`) should the odds ratio be calculated, default is `TRUE` |
|
11 |
#' @param perform_analysis (`string`) option to display statistical comparisons using stratified analyses, |
|
12 |
#' or unstratified analyses, or both, e.g. `c("unstrat", "strat")`. Only unstratified will be displayed by default |
|
13 |
#' @param strata (`string`) stratification factors, e.g. `strata = c("STRATA1", "STRATA2")`, by default as NULL |
|
14 |
#' @param conf_level (`numeric`) the level of confidence interval, default is 0.95. |
|
15 |
#' @param methods (`list`) a named list, use a named list to control, for example: |
|
16 |
#' `methods = list(prop_conf_method = "wald", |
|
17 |
#' diff_conf_method = "wald", |
|
18 |
#' strat_diff_conf_method = "ha", |
|
19 |
#' diff_pval_method = "fisher", |
|
20 |
#' strat_diff_pval_method = "schouten")` |
|
21 |
#' `prop_conf_method` controls the methods of calculating proportion confidence interval, |
|
22 |
#' `diff_conf_method` controls the methods of calculating unstratified difference confidence interval, |
|
23 |
#' `strat_diff_conf_method` controls the methods of calculating stratified difference confidence interval, |
|
24 |
#' `diff_pval_method` controls the methods of calculating unstratified p-value for odds ratio, |
|
25 |
#' `strat_diff_pval_method` controls the methods of calculating stratified p-value for odds ratio, |
|
26 |
#' see more details in `tern` |
|
27 |
#' @returns the main function returns an `rtables` object. |
|
28 |
#' |
|
29 |
#' @details |
|
30 |
#' * No overall value. |
|
31 |
#' |
|
32 |
#' @export |
|
33 |
#' |
|
34 |
rspt01_main <- function(adam_db, |
|
35 |
dataset = "adrs", |
|
36 |
arm_var = "ARM", |
|
37 |
ref_group = NULL, |
|
38 |
odds_ratio = TRUE, |
|
39 |
perform_analysis = "unstrat", |
|
40 |
strata = NULL, |
|
41 |
conf_level = 0.95, |
|
42 |
methods = list(), |
|
43 |
...) { |
|
44 | 1x |
assert_string(dataset) |
45 | 1x |
assert_all_tablenames(adam_db, "adsl", dataset) |
46 | 1x |
assert_string(arm_var) |
47 | 1x |
assert_string(ref_group, null.ok = TRUE) |
48 | 1x |
assert_flag(odds_ratio) |
49 | 1x |
assert_subset(perform_analysis, c("unstrat", "strat")) |
50 | 1x |
assert_character( |
51 | 1x |
strata, |
52 | 1x |
null.ok = !"strat" %in% perform_analysis, |
53 | 1x |
min.len = as.integer(!"strat" %in% perform_analysis) |
54 |
) |
|
55 | 1x |
df_label <- sprintf("adam_db$%s", dataset) |
56 | 1x |
assert_valid_variable( |
57 | 1x |
adam_db$adsl, c("USUBJID", arm_var), |
58 | 1x |
types = list(c("character", "factor")) |
59 |
) |
|
60 | 1x |
assert_valid_variable( |
61 | 1x |
adam_db[[dataset]], c("USUBJID", arm_var, "RSP_LAB"), |
62 | 1x |
types = list(c("character", "factor")), label = df_label |
63 |
) |
|
64 | 1x |
assert_valid_variable(adam_db[[dataset]], "IS_RSP", types = list("logical"), label = df_label) |
65 | 1x |
assert_valid_variable( |
66 | 1x |
adam_db[[dataset]], c("PARAMCD", "PARAM"), |
67 | 1x |
types = list(c("character", "factor")), label = df_label |
68 |
) |
|
69 | 1x |
assert_single_value(adam_db[[dataset]]$PARAMCD, label = sprintf("adam_db$%s$PARAMCD", dataset)) |
70 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db[[dataset]], arm_var) |
71 | 1x |
assert_subset(ref_group, lvls(adam_db[[dataset]][[arm_var]])) |
72 | ||
73 | 1x |
ref_group <- ref_group %||% lvls(adam_db[[dataset]][[arm_var]])[1] |
74 | ||
75 | 1x |
lyt <- rspt01_lyt( |
76 | 1x |
arm_var = arm_var, |
77 | 1x |
rsp_var = "IS_RSP", |
78 | 1x |
ref_group = ref_group, |
79 | 1x |
odds_ratio = odds_ratio, |
80 | 1x |
perform_analysis = perform_analysis, |
81 | 1x |
strata = strata, |
82 | 1x |
conf_level = conf_level, |
83 | 1x |
methods = methods |
84 |
) |
|
85 | ||
86 | 1x |
tbl <- build_table(lyt, adam_db[[dataset]], alt_counts_df = adam_db$adsl) |
87 | ||
88 | 1x |
tbl |
89 |
} |
|
90 | ||
91 |
#' `rspt01` Layout |
|
92 |
#' |
|
93 |
#' @inheritParams gen_args |
|
94 |
#' |
|
95 |
#' @keywords internal |
|
96 |
#' |
|
97 |
rspt01_lyt <- function(arm_var, |
|
98 |
rsp_var, |
|
99 |
ref_group, |
|
100 |
odds_ratio, |
|
101 |
perform_analysis, |
|
102 |
strata, |
|
103 |
conf_level, |
|
104 |
methods) { |
|
105 | 13x |
lyt01 <- basic_table(show_colcounts = TRUE) %>% |
106 | 13x |
split_cols_by(var = arm_var, ref_group = ref_group) %>% |
107 | 13x |
estimate_proportion( |
108 | 13x |
vars = rsp_var, |
109 | 13x |
conf_level = conf_level, |
110 | 13x |
method = methods[["prop_conf_method"]] %||% "waldcc", |
111 | 13x |
table_names = "est_prop" |
112 |
) |
|
113 | ||
114 | 13x |
for (perform in perform_analysis) { |
115 | 18x |
lyt01 <- lyt01 %>% |
116 | 18x |
proportion_lyt( |
117 | 18x |
arm_var = arm_var, |
118 | 18x |
odds_ratio = odds_ratio, |
119 | 18x |
strata = if (perform == "strat") strata else NULL, |
120 | 18x |
conf_level = conf_level, |
121 | 18x |
methods = methods, |
122 | 18x |
rsp_var = rsp_var |
123 |
) |
|
124 |
} |
|
125 | ||
126 | 13x |
lyt <- lyt01 %>% |
127 | 13x |
estimate_multinomial_response( |
128 | 13x |
var = "RSP_LAB", |
129 | 13x |
conf_level = conf_level, |
130 | 13x |
method = methods[["prop_conf_method"]] %||% "waldcc" |
131 |
) |
|
132 | ||
133 | 13x |
lyt |
134 |
} |
|
135 | ||
136 |
#' @describeIn rspt01 Preprocessing |
|
137 |
#' |
|
138 |
#' @inheritParams gen_args |
|
139 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
140 |
#' @export |
|
141 |
#' |
|
142 |
rspt01_pre <- function(adam_db, ...) { |
|
143 | 1x |
adam_db$adrs <- adam_db$adrs %>% |
144 | 1x |
mutate(RSP_LAB = tern::d_onco_rsp_label(.data$AVALC)) %>% |
145 | 1x |
mutate(IS_RSP = .data$AVALC %in% c("CR", "PR")) |
146 | 1x |
adam_db |
147 |
} |
|
148 | ||
149 |
#' @describeIn rspt01 Postprocessing |
|
150 |
#' |
|
151 |
#' @inheritParams gen_args |
|
152 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
153 |
#' @export |
|
154 |
#' |
|
155 |
rspt01_post <- function(tlg, prune_0 = TRUE, ...) { |
|
156 | ! |
if (prune_0) { |
157 | ! |
tlg <- smart_prune(tlg) |
158 |
} |
|
159 | ! |
std_postprocessing(tlg) |
160 |
} |
|
161 | ||
162 |
#' `RSPT01` Binary Outcomes Summary. |
|
163 |
#' |
|
164 |
#' `RSPT01` template may be used to summarize any binary outcome or response variable at |
|
165 |
#' a single time point. Typical application for oncology |
|
166 |
#' |
|
167 |
#' @include chevron_tlg-S4class.R |
|
168 |
#' @export |
|
169 |
#' |
|
170 |
#' @examples |
|
171 |
#' library(dplyr) |
|
172 |
#' library(dunlin) |
|
173 |
#' |
|
174 |
#' proc_data <- log_filter(syn_data, PARAMCD == "BESRSPI", "adrs") |
|
175 |
#' |
|
176 |
#' run(rspt01, proc_data) |
|
177 |
#' |
|
178 |
#' run(rspt01, proc_data, |
|
179 |
#' odds_ratio = FALSE, perform_analysis = c("unstrat", "strat"), |
|
180 |
#' strata = c("STRATA1", "STRATA2"), methods = list(diff_pval_method = "fisher") |
|
181 |
#' ) |
|
182 |
rspt01 <- chevron_t( |
|
183 |
main = rspt01_main, |
|
184 |
preprocess = rspt01_pre, |
|
185 |
postprocess = rspt01_post |
|
186 |
) |
1 |
# lbt07 ---- |
|
2 | ||
3 |
#' @describeIn lbt07 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param param_var (`string`) the name of the column storing the parameters name. |
|
7 |
#' @param grad_dir_var (`string`) the name of the column storing the grade direction variable which is required in |
|
8 |
#' order to obtain the correct denominators when building the layout as it is used to define row splitting. |
|
9 |
#' @param grad_anl_var (`string`) the name of the column storing toxicity grade variable where all negative values from |
|
10 |
#' `ATOXGR` are replaced by their absolute values. |
|
11 |
#' @returns the main function returns an `rtables` object. |
|
12 |
#' |
|
13 |
#' @details |
|
14 |
#' * Split columns by arm, typically `ACTARM`. |
|
15 |
#' |
|
16 |
#' @note |
|
17 |
#' * `adam_db` object must contain an `adlb` table with columns `"USUBJID"`, `"ATOXGR"`, |
|
18 |
#' `"ONTRTFL"` and column specified by `arm_var`. |
|
19 |
#' |
|
20 |
#' @export |
|
21 |
#' |
|
22 |
lbt07_main <- function(adam_db, |
|
23 |
arm_var = "ACTARM", |
|
24 |
lbl_overall = NULL, |
|
25 |
param_var = "PARAM", |
|
26 |
grad_dir_var = "GRADE_DIR", |
|
27 |
grad_anl_var = "GRADE_ANL", |
|
28 |
...) { |
|
29 | 1x |
assert_all_tablenames(adam_db, c("adsl", "adlb")) |
30 | 1x |
assert_string(arm_var) |
31 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
32 | 1x |
assert_string(param_var) |
33 | 1x |
assert_string(grad_dir_var) |
34 | 1x |
assert_string(grad_anl_var) |
35 | 1x |
assert_valid_variable( |
36 | 1x |
adam_db$adlb, c("ATOXGR", param_var, grad_dir_var, grad_anl_var), |
37 | 1x |
types = list(c("character", "factor")) |
38 |
) |
|
39 | 1x |
assert_valid_variable(adam_db$adlb, c("USUBJID"), types = list(c("character", "factor")), empty_ok = TRUE) |
40 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID"), types = list(c("character", "factor"))) |
41 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adlb, arm_var) |
42 | ||
43 | 1x |
lbl_overall <- render_safe(lbl_overall) |
44 | 1x |
lbl_param_var <- var_labels_for(adam_db$adlb, param_var) |
45 | 1x |
lbl_grad_dir_var <- var_labels_for(adam_db$adlb, grad_dir_var) |
46 | ||
47 | 1x |
map <- expand.grid( |
48 | 1x |
PARAM = levels(adam_db$adlb[[param_var]]), |
49 | 1x |
GRADE_DIR = c("LOW", "HIGH"), |
50 | 1x |
GRADE_ANL = as.character(1:4), |
51 | 1x |
stringsAsFactors = FALSE |
52 |
) %>% |
|
53 | 1x |
arrange(.data$PARAM, desc(.data$GRADE_DIR), .data$GRADE_ANL) |
54 | ||
55 | 1x |
names(map) <- c(param_var, grad_dir_var, grad_anl_var) |
56 | ||
57 | 1x |
lyt <- lbt07_lyt( |
58 | 1x |
arm_var = arm_var, |
59 | 1x |
lbl_overall = lbl_overall, |
60 | 1x |
lbl_param_var = lbl_param_var, |
61 | 1x |
lbl_grad_dir_var = lbl_grad_dir_var, |
62 | 1x |
param_var = param_var, |
63 | 1x |
grad_dir_var = grad_dir_var, |
64 | 1x |
grad_anl_var = grad_anl_var, |
65 | 1x |
map = map |
66 |
) |
|
67 | ||
68 | 1x |
tbl <- build_table(lyt, adam_db$adlb, alt_counts_df = adam_db$adsl) |
69 | ||
70 | 1x |
tbl |
71 |
} |
|
72 | ||
73 |
#' `lbt07` Layout |
|
74 |
#' |
|
75 |
#' @inheritParams gen_args |
|
76 |
#' @inheritParams lbt07_main |
|
77 |
#' |
|
78 |
#' @param lbl_param_var (`string`) label of the `param_var` variable. |
|
79 |
#' @param lbl_grad_dir_var (`string`) label for the `grad_dir_var` variable. |
|
80 |
#' @param map (`data.frame`) mapping of `PARAM`s to directions of abnormality. |
|
81 |
#' |
|
82 |
#' @keywords internal |
|
83 |
#' |
|
84 |
lbt07_lyt <- function(arm_var, |
|
85 |
lbl_overall, |
|
86 |
lbl_param_var, |
|
87 |
lbl_grad_dir_var, |
|
88 |
param_var, |
|
89 |
grad_dir_var, |
|
90 |
grad_anl_var, |
|
91 |
map) { |
|
92 | 2x |
basic_table(show_colcounts = TRUE) %>% |
93 | 2x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
94 | 2x |
split_rows_by( |
95 | 2x |
param_var, |
96 | 2x |
label_pos = "topleft", |
97 | 2x |
split_label = lbl_param_var |
98 |
) %>% |
|
99 | 2x |
summarize_num_patients( |
100 | 2x |
var = "USUBJID", |
101 | 2x |
required = "ATOXGR", |
102 | 2x |
.stats = "unique_count" |
103 |
) %>% |
|
104 | 2x |
split_rows_by( |
105 | 2x |
grad_dir_var, |
106 | 2x |
label_pos = "topleft", |
107 | 2x |
split_label = lbl_grad_dir_var, |
108 | 2x |
split_fun = trim_levels_to_map(map) |
109 |
) %>% |
|
110 | 2x |
count_abnormal_by_worst_grade( |
111 | 2x |
var = grad_anl_var, |
112 | 2x |
variables = list(id = "USUBJID", param = param_var, grade_dir = grad_dir_var), |
113 | 2x |
.formats = list(count_fraction = tern::format_count_fraction_fixed_dp), |
114 | 2x |
.indent_mods = 4L |
115 |
) %>% |
|
116 | 2x |
append_topleft(" Highest NCI CTCAE Grade") |
117 |
} |
|
118 | ||
119 |
#' @describeIn lbt07 Preprocessing |
|
120 |
#' |
|
121 |
#' @inheritParams gen_args |
|
122 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
123 |
#' @export |
|
124 |
#' |
|
125 |
lbt07_pre <- function(adam_db, ...) { |
|
126 | 1x |
adam_db$adlb <- adam_db$adlb %>% |
127 | 1x |
mutate( |
128 | 1x |
ATOXGR = reformat(.data$ATOXGR, missing_rule) |
129 |
) %>% |
|
130 | 1x |
filter( |
131 | 1x |
.data$ATOXGR != "<Missing>", |
132 | 1x |
.data$ONTRTFL == "Y", |
133 | 1x |
.data$WGRLOFL == "Y" | .data$WGRHIFL == "Y" |
134 |
) %>% |
|
135 | 1x |
mutate( |
136 | 1x |
GRADE_DIR = factor( |
137 | 1x |
case_when( |
138 | 1x |
ATOXGR %in% c("-1", "-2", "-3", "-4") & .data$WGRLOFL == "Y" ~ "LOW", |
139 | 1x |
ATOXGR == "0" ~ "ZERO", |
140 | 1x |
ATOXGR %in% c("1", "2", "3", "4") & .data$WGRHIFL == "Y" ~ "HIGH", |
141 | 1x |
TRUE ~ "NONE" |
142 |
), |
|
143 | 1x |
levels = c("LOW", "ZERO", "HIGH", "NONE") |
144 |
), |
|
145 | 1x |
GRADE_ANL = factor(.data$ATOXGR, levels = c(-4:4), labels = abs(c(-4:4))), |
146 | 1x |
PARAM = as.factor(trimws(stringr::str_remove_all(.data$PARAM, "\\(.+?\\)"))) |
147 |
) |
|
148 | ||
149 | 1x |
adam_db$adlb <- adam_db$adlb %>% |
150 | 1x |
mutate( |
151 | 1x |
PARAM = with_label(.data$PARAM, "Parameter"), |
152 | 1x |
GRADE_DIR = with_label(.data$GRADE_DIR, "Direction of Abnormality"), |
153 | 1x |
GRADE_ANL = with_label(.data$GRADE_ANL, "Toxicity Grade") |
154 |
) |
|
155 | ||
156 | 1x |
adam_db |
157 |
} |
|
158 | ||
159 |
#' @describeIn lbt07 Postprocessing |
|
160 |
#' |
|
161 |
#' @inheritParams gen_args |
|
162 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
163 |
#' @export |
|
164 |
#' |
|
165 |
lbt07_post <- function(tlg, prune_0 = TRUE, ...) { |
|
166 | 1x |
if (prune_0) { |
167 | 1x |
tlg <- smart_prune(tlg) |
168 |
} |
|
169 | 1x |
std_postprocessing(tlg) |
170 |
} |
|
171 | ||
172 |
#' `LBT07` Table 1 (Default) Laboratory Test Results and Change from Baseline by Visit. |
|
173 |
#' |
|
174 |
#' The `LBT07` table provides an |
|
175 |
#' overview of the analysis values and its change from baseline of each respective arm over the course of the trial. |
|
176 |
#' @include chevron_tlg-S4class.R |
|
177 |
#' @export |
|
178 |
#' |
|
179 |
#' @examples |
|
180 |
#' run(lbt07, syn_data) |
|
181 |
lbt07 <- chevron_t( |
|
182 |
main = lbt07_main, |
|
183 |
preprocess = lbt07_pre, |
|
184 |
postprocess = lbt07_post |
|
185 |
) |
1 |
#' @keywords internal |
|
2 |
split_and_summ_num_patients <- function(lyt, var, label, stats, summarize_labels, split_indent, section_div, ...) { |
|
3 | 21x |
assert_string(var) |
4 | 21x |
assert_string(label) |
5 | 21x |
lyt <- lyt %>% |
6 | 21x |
split_rows_by( |
7 | 21x |
var, |
8 | 21x |
child_labels = "visible", |
9 | 21x |
nested = TRUE, |
10 | 21x |
split_fun = rtables::drop_split_levels, |
11 | 21x |
label_pos = "topleft", |
12 | 21x |
split_label = label, |
13 | 21x |
indent_mod = split_indent, |
14 | 21x |
section_div = section_div |
15 |
) |
|
16 | 21x |
if (length(stats) > 0) { |
17 | 21x |
lyt <- lyt %>% |
18 | 21x |
summarize_num_patients( |
19 | 21x |
var = "USUBJID", |
20 | 21x |
.stats = stats, |
21 | 21x |
.labels = setNames(summarize_labels, stats), |
22 |
... |
|
23 |
) |
|
24 |
} |
|
25 | ||
26 | 21x |
lyt |
27 |
} |
|
28 | ||
29 |
#' @keywords internal |
|
30 |
get_sort_path <- function(x) { |
|
31 | 60x |
assert_character(x, null.ok = TRUE) |
32 | 60x |
x2 <- as.character(rbind(x, rep("*", length(x)))) |
33 | 60x |
x2[-length(x2)] |
34 |
} |
|
35 | ||
36 |
#' @keywords internal |
|
37 |
tlg_sort_by_vars <- function(tlg, vars, scorefun = cont_n_allcols, ...) { |
|
38 | 25x |
purrr::reduce( |
39 | 25x |
.x = lapply(seq_len(length(vars)), function(i) vars[seq_len(i)]), |
40 | 25x |
.f = tlg_sort_by_var, |
41 | 25x |
.init = tlg, |
42 | 25x |
scorefun = scorefun, |
43 |
... |
|
44 |
) |
|
45 |
} |
|
46 | ||
47 |
#' @keywords internal |
|
48 |
tlg_sort_by_var <- function(tlg, var, scorefun = cont_n_allcols, ...) { |
|
49 | 50x |
assert_character(var) |
50 | 50x |
if (length(var) == 0) { |
51 | ! |
return(tlg) |
52 |
} |
|
53 | 50x |
var_path <- get_sort_path(var) |
54 | 50x |
tlg %>% |
55 | 50x |
valid_sort_at_path( |
56 | 50x |
path = var_path, |
57 | 50x |
scorefun = scorefun, |
58 |
... |
|
59 |
) |
|
60 |
} |
|
61 | ||
62 |
#' @keywords internal |
|
63 |
valid_sort_at_path <- function(tt, path, scorefun, ...) { |
|
64 | 60x |
if (valid_row_path(tt, path)) { |
65 | 53x |
tryCatch( |
66 | 53x |
sort_at_path(tt, path, scorefun, ...), |
67 | 53x |
error = function(e) { |
68 | ! |
tt |
69 |
} |
|
70 |
) |
|
71 |
} else { |
|
72 | 7x |
tt |
73 |
} |
|
74 |
} |
|
75 | ||
76 |
#' @keywords internal |
|
77 |
valid_row_path <- function(tlg, row_path) { |
|
78 | 60x |
if (nrow(tlg) == 0) { |
79 | 2x |
return(TRUE) |
80 |
} |
|
81 | 58x |
rpaths <- lapply(row_paths(tlg), unname) |
82 | 58x |
non_star <- which(row_path != "*") + 1 |
83 | 58x |
rpaths_choice <- unique(lapply(rpaths, `[`, non_star)) |
84 | 58x |
any(vapply(rpaths_choice, identical, FUN.VALUE = TRUE, y = row_path[non_star - 1])) |
85 |
} |
|
86 | ||
87 |
#' Count patients recursively |
|
88 |
#' |
|
89 |
#' @param lyt (`PreDataTableLayouts`) `rtable` layout. |
|
90 |
#' @param anl_vars Named (`list`) of analysis variables. |
|
91 |
#' @param anl_lbls (`character`) of labels. |
|
92 |
#' @param lbl_vars Named (`list`) of analysis labels. |
|
93 |
#' |
|
94 |
#' @keywords internal |
|
95 |
count_patients_recursive <- function(lyt, anl_vars, anl_lbls, lbl_vars) { |
|
96 | 8x |
assert_list(anl_vars, names = "unique", types = "character") |
97 | 8x |
assert_character(anl_lbls, min.chars = 1L, len = length(anl_vars)) |
98 | 8x |
nms <- names(anl_vars) |
99 | 8x |
for (k in seq_len(length(anl_vars))) { |
100 | 9x |
lyt <- lyt %>% |
101 | 9x |
count_patients_with_flags( |
102 | 9x |
var = "USUBJID", |
103 | 9x |
flag_variables = setNames(lbl_vars[[k]], anl_vars[[k]]), |
104 | 9x |
denom = "N_col", |
105 | 9x |
var_labels = anl_lbls[k], |
106 | 9x |
show_labels = "visible", |
107 | 9x |
table_names = nms[k], |
108 | 9x |
.indent_mods = 0L |
109 |
) |
|
110 |
} |
|
111 | ||
112 | 8x |
lyt |
113 |
} |
|
114 | ||
115 |
#' @keywords internal |
|
116 |
score_all_sum <- function(tt) { |
|
117 | 147x |
cleaf <- collect_leaves(tt)[[1]] |
118 | 147x |
if (NROW(cleaf) == 0) { |
119 | ! |
stop("score_all_sum score function used at subtable [", obj_name(tt), "] that has no content.") |
120 |
} |
|
121 | 147x |
sum(sapply(row_values(cleaf), function(cv) cv[1])) |
122 |
} |
|
123 | ||
124 |
#' @keywords internal |
|
125 |
summarize_row <- function(lyt, vars, afun, ...) { |
|
126 | 2x |
summarize_row_groups(lyt = lyt, var = vars, cfun = afun, ...) |
127 |
} |
|
128 | ||
129 |
#' Summary factor allowing NA |
|
130 |
#' @param x (`factor`) input. |
|
131 |
#' @param denom (`string`) denominator choice. |
|
132 |
#' @param .N_row (`integer`) number of rows in row-split dataset. |
|
133 |
#' @param .N_col (`integer`) number of rows in column-split dataset. |
|
134 |
#' @param ... Not used |
|
135 |
#' |
|
136 |
#' @keywords internal |
|
137 |
s_summary_na <- function(x, labelstr, denom = c("n", "N_row", "N_col"), .N_row, .N_col, ...) { # nolint |
|
138 | 210x |
denom <- match.arg(denom) |
139 | 210x |
y <- list() |
140 | 210x |
y$n <- length(x) |
141 | 210x |
y$count <- as.list(table(x, useNA = "no")) |
142 | 210x |
dn <- switch(denom, |
143 | 210x |
n = length(x), |
144 | 210x |
N_row = .N_row, |
145 | 210x |
N_col = .N_col |
146 |
) |
|
147 | 210x |
y$count_fraction <- lapply(y$count, function(x) { |
148 | 714x |
c(x, ifelse(dn > 0, x / dn, 0)) |
149 |
}) |
|
150 | 210x |
y$n_blq <- sum(grepl("BLQ|LTR|<[1-9]", x)) |
151 | ||
152 | 210x |
y |
153 |
} |
|
154 | ||
155 |
#' Summarize variables allow `NA` |
|
156 |
#' |
|
157 |
#' @keywords internal |
|
158 |
summarize_vars_allow_na <- function( |
|
159 |
lyt, vars, var_labels = vars, |
|
160 |
nested = TRUE, ..., show_labels = "default", table_names = vars, |
|
161 |
section_div = NA_character_, .stats = c("n", "count_fraction"), |
|
162 |
.formats = list(count_fraction = format_count_fraction_fixed_dp), .labels = NULL, .indent_mods = NULL, inclNAs = TRUE) { # nolint |
|
163 | 7x |
afun <- make_afun(s_summary_na, .stats, .formats, .labels, .indent_mods, .ungroup_stats = c("count_fraction")) |
164 | 7x |
analyze( |
165 | 7x |
lyt = lyt, vars = vars, var_labels = var_labels, |
166 | 7x |
afun = afun, nested = nested, extra_args = list(...), |
167 | 7x |
inclNAs = inclNAs, show_labels = show_labels, table_names = table_names, |
168 | 7x |
section_div = section_div |
169 |
) |
|
170 |
} |
|
171 | ||
172 |
#' Count or summarize by groups |
|
173 |
#' |
|
174 |
#' @param lyt (`PreDataTableLayouts`) `rtable` layout. |
|
175 |
#' @param var (`string`) of analysis variable. |
|
176 |
#' @param level (`string`) level to be displayed. |
|
177 |
#' @param detail_vars (`character`) of variables for detail information. |
|
178 |
#' |
|
179 |
#' @keywords internal |
|
180 |
count_or_summarize <- function(lyt, var, level, detail_vars, indent_mod = 0L, ...) { |
|
181 | 27x |
assert_string(level) |
182 | 27x |
if (is.null(detail_vars)) { |
183 | 20x |
lyt <- lyt %>% |
184 | 20x |
count_values( |
185 | 20x |
var, |
186 | 20x |
values = level, |
187 | 20x |
table_names = paste(var, level, sep = "_"), |
188 | 20x |
.formats = list(count_fraction = format_count_fraction_fixed_dp), |
189 | 20x |
.indent_mods = indent_mod, |
190 |
... |
|
191 |
) |
|
192 |
} else { |
|
193 | 7x |
lyt <- lyt %>% |
194 | 7x |
split_rows_by(var, split_fun = keep_split_levels(level), indent_mod = indent_mod) %>% |
195 | 7x |
summarize_row_groups( |
196 | 7x |
format = format_count_fraction_fixed_dp |
197 |
) %>% |
|
198 | 7x |
split_rows_by_recursive(detail_vars[-length(detail_vars)], split_fun = drop_split_levels) %>% |
199 | 7x |
analyze_vars( |
200 | 7x |
detail_vars[length(detail_vars)], |
201 | 7x |
.stats = "count_fraction", |
202 | 7x |
denom = "N_col", |
203 | 7x |
show_labels = "hidden", |
204 | 7x |
.formats = list(count_fraction = format_count_fraction_fixed_dp), |
205 |
... |
|
206 |
) |
|
207 |
} |
|
208 | ||
209 | 27x |
lyt |
210 |
} |
|
211 | ||
212 |
#' Count or summarize by groups |
|
213 |
#' |
|
214 |
#' @param lyt (`PreDataTableLayouts`) `rtable` layout. |
|
215 |
#' @param row_split_var (`character`) variable to split rows by. |
|
216 |
#' @param ... Further arguments for `split_rows_by` |
|
217 |
#' |
|
218 |
#' @keywords internal |
|
219 |
split_rows_by_recursive <- function(lyt, row_split_var, ...) { |
|
220 | 42x |
args <- list(...) |
221 | 42x |
for (i in seq_len(length(row_split_var))) { |
222 | 23x |
args_i <- lapply(args, obtain_value, index = i) |
223 | 23x |
lyt <- do_call( |
224 | 23x |
split_rows_by, |
225 | 23x |
c( |
226 | 23x |
list( |
227 | 23x |
lyt = lyt, |
228 | 23x |
row_split_var |
229 |
), |
|
230 | 23x |
args_i |
231 |
) |
|
232 |
) |
|
233 |
} |
|
234 | ||
235 | 42x |
lyt |
236 |
} |
|
237 | ||
238 |
#' Obtain value from a vector |
|
239 |
#' |
|
240 |
#' @keywords internal |
|
241 |
obtain_value <- function(obj, index) { |
|
242 | 65x |
if (is.list(obj)) { |
243 | ! |
return(obj[[index]]) |
244 |
} |
|
245 | 65x |
if (is.vector(obj) && length(obj) >= index) { |
246 | 63x |
return(obj[index]) |
247 |
} |
|
248 | 2x |
return(obj) |
249 |
} |
|
250 | ||
251 |
#' Get page by value |
|
252 |
#' |
|
253 |
#' @keywords internal |
|
254 |
get_page_by <- function(var, vars) { |
|
255 | 35x |
assert_character(vars, null.ok = TRUE) |
256 | 35x |
assert_character(var, null.ok = TRUE, max.len = 1L) |
257 | 35x |
ret <- rep(FALSE, length(vars)) |
258 | 35x |
if (is.null(var) || length(var) == 0) { |
259 | 16x |
return(ret) |
260 |
} |
|
261 | 19x |
index <- match(var, vars) |
262 | 19x |
assert_int(index, na.ok = TRUE) |
263 | 19x |
if (is.na(index)) { |
264 | ! |
return(ret) |
265 |
} |
|
266 | 19x |
ret[seq_len(index)] <- TRUE |
267 | 19x |
return(ret) |
268 |
} |
|
269 | ||
270 |
#' Proportion layout |
|
271 |
#' |
|
272 |
#' @inheritParams rspt01_main |
|
273 |
#' @param lyt layout created by `rtables` |
|
274 |
#' |
|
275 |
#' @keywords internal |
|
276 |
proportion_lyt <- function(lyt, arm_var, methods, strata, conf_level, odds_ratio = TRUE, rsp_var = "IS_RSP") { |
|
277 | 18x |
non_stratified <- length(strata) == 0L |
278 | 18x |
lyt <- lyt %>% |
279 | 18x |
estimate_proportion_diff( |
280 | 18x |
vars = rsp_var, |
281 | 18x |
show_labels = "visible", |
282 | 18x |
var_labels = if (non_stratified) "Unstratified Analysis" else "Stratified Analysis", |
283 | 18x |
conf_level = conf_level, |
284 | 18x |
method = if (non_stratified) { |
285 | 11x |
methods[["diff_conf_method"]] %||% "waldcc" |
286 |
} else { |
|
287 | 7x |
methods[["strat_diff_conf_method"]] %||% "cmh" |
288 |
}, |
|
289 | 18x |
variables = list(strata = strata), |
290 | 18x |
table_names = if (non_stratified) "est_prop_diff" else "est_prop_diff_strat" |
291 |
) %>% |
|
292 | 18x |
test_proportion_diff( |
293 | 18x |
vars = rsp_var, |
294 | 18x |
method = if (non_stratified) { |
295 | 11x |
methods[["diff_pval_method"]] %||% "chisq" |
296 |
} else { |
|
297 | 7x |
methods[["strat_diff_pval_method"]] %||% "cmh" |
298 |
}, |
|
299 | 18x |
variables = list(strata = strata), |
300 | 18x |
table_names = if (non_stratified) "test_prop_diff" else "test_prop_diff_strat" |
301 |
) |
|
302 | ||
303 | 18x |
if (odds_ratio) { |
304 | 14x |
lyt <- lyt %>% |
305 | 14x |
estimate_odds_ratio( |
306 | 14x |
vars = rsp_var, |
307 | 14x |
variables = if (non_stratified) list(strata = strata, arm = arm_var), |
308 | 14x |
table_names = if (non_stratified) "est_or" else "est_or_strat" |
309 |
) |
|
310 |
} |
|
311 | ||
312 | 18x |
lyt |
313 |
} |
|
314 | ||
315 |
#' Helper function to add a row split if specified |
|
316 |
#' |
|
317 |
#' @param lyt (`PreDataTableLayouts`) object. |
|
318 |
#' @param var (`string`) the name of the variable initiating a new row split. |
|
319 |
#' @param lbl_var (`string`)the label of the variable `var`. |
|
320 |
#' |
|
321 |
#' @keywords internal |
|
322 |
#' |
|
323 |
#' @returns `PreDataTableLayouts` object. |
|
324 |
ifneeded_split_row <- function(lyt, var, lbl_var) { |
|
325 | 2x |
if (is.null(var)) { |
326 | 1x |
lyt |
327 |
} else { |
|
328 | 1x |
split_rows_by(lyt, var, |
329 | 1x |
label_pos = "topleft", |
330 | 1x |
split_label = lbl_var |
331 |
) |
|
332 |
} |
|
333 |
} |
|
334 | ||
335 |
#' Helper function to add a column split if specified |
|
336 |
#' |
|
337 |
#' @param lyt (`rtables`) object. |
|
338 |
#' @param var (`string`) the name of the variable initiating a new column split. |
|
339 |
#' @param ... Additional arguments for `split_cols_by`. |
|
340 |
#' |
|
341 |
#' @keywords internal |
|
342 |
#' |
|
343 |
#' @returns `rtables` object. |
|
344 |
ifneeded_split_col <- function(lyt, var, ...) { |
|
345 | 10x |
if (is.null(var)) { |
346 | 5x |
lyt |
347 |
} else { |
|
348 | 5x |
split_cols_by( |
349 | 5x |
lyt = lyt, |
350 | 5x |
var = var, |
351 |
... |
|
352 |
) |
|
353 |
} |
|
354 |
} |
|
355 | ||
356 |
#' Count Children |
|
357 |
#' |
|
358 |
#' @keywords internal |
|
359 |
count_children <- function(x) { |
|
360 | 2516x |
assert_true(rtables::is_rtable(x)) |
361 | 2516x |
if (is(x, "ElementaryTable")) { |
362 | 1074x |
return(length(x@children)) |
363 |
} |
|
364 | 1442x |
sum(vapply( |
365 | 1442x |
tree_children(x), |
366 | 1442x |
count_children, |
367 | 1442x |
FUN.VALUE = 0 |
368 |
)) |
|
369 |
} |
|
370 | ||
371 |
has_overall_col <- function(lbl_overall) { |
|
372 | ! |
!is.null(lbl_overall) && !identical(lbl_overall, "") |
373 |
} |
|
374 | ||
375 |
ifneeded_add_overall_col <- function(lyt, lbl_overall) { |
|
376 | ! |
if (has_overall_col(lbl_overall)) { |
377 | ! |
add_overall_col(lyt, label = lbl_overall) |
378 |
} else { |
|
379 | ! |
lyt |
380 |
} |
|
381 |
} |
|
382 | ||
383 |
split_cols_by_with_overall <- function(lyt, col_var, lbl_overall, ref_group = NULL) { |
|
384 | 190x |
if (is.null(col_var)) { |
385 | 17x |
lyt |
386 |
} else { |
|
387 | 173x |
split_cols_by( |
388 | 173x |
lyt, col_var, |
389 | 173x |
split_fun = if (!is.null(lbl_overall) && !identical(lbl_overall, "")) { |
390 | 29x |
add_overall_level(lbl_overall, first = FALSE) |
391 |
}, |
|
392 | 173x |
ref_group = ref_group |
393 |
) |
|
394 |
} |
|
395 |
} |
|
396 | ||
397 |
#' Analyze skip baseline |
|
398 |
#' |
|
399 |
#' @param x value to analyze |
|
400 |
#' @param .var variable name. |
|
401 |
#' @param .spl_context split context. |
|
402 |
#' @param paramcdvar (`string`) name of parameter code. |
|
403 |
#' @param visitvar (`string`) name of the visit variable. |
|
404 |
#' @param skip Named (`character`) indicating the pairs to skip in analyze. |
|
405 |
#' @param .stats (`character`) See `tern::analyze_variables`. |
|
406 |
#' @param .labels (`character`) See `tern::analyze_variables`. |
|
407 |
#' @param .indent_mods (`integer`) See `tern::analyze_variables`. |
|
408 |
#' @param .N_col (`int`) See `tern::analyze_variables`. |
|
409 |
#' @param .N_row (`int`) See `tern::analyze_variables`. |
|
410 |
#' @param ... additional arguments for `tern::a_summary`. |
|
411 |
#' @inheritParams cfbt01_main |
|
412 |
#' |
|
413 |
#' @keywords internal |
|
414 |
afun_skip <- function( |
|
415 |
x, .var, .spl_context, paramcdvar, visitvar, skip, |
|
416 |
precision, .stats, .labels = NULL, .indent_mods = NULL, .N_col, .N_row, ...) { # nolint |
|
417 | 1116x |
param_val <- .spl_context$value[which(.spl_context$split == paramcdvar)] |
418 |
# Identify context |
|
419 | 1116x |
split_level <- .spl_context$value[which(.spl_context$split == visitvar)] |
420 | 1116x |
pcs <- if (.var %in% names(skip) && split_level %in% skip[[.var]]) { |
421 | 1116x |
NA |
422 |
} else { |
|
423 | 1029x |
precision[[param_val]] %||% precision[["default"]] %||% 2 |
424 |
} |
|
425 | ||
426 | 1116x |
fmts <- lapply(.stats, summary_formats, pcs = pcs, ne = NULL) |
427 | 1116x |
names(fmts) <- .stats |
428 | 1116x |
fmts_na <- lapply(.stats, summary_formats, pcs = pcs, ne = tern::default_na_str()) |
429 | 1116x |
ret <- tern::a_summary( |
430 | 1116x |
.stats = .stats, .formats = fmts, .labels = .labels, .indent_mods = .indent_mods, |
431 | 1116x |
x = x, .var = .var, .spl_context = .spl_context, .N_col = .N_col, .N_row = .N_row, ... |
432 |
) |
|
433 | 1116x |
for (i in seq_len(length(ret))) { |
434 | 4464x |
attr(ret[[i]], "format_na_str") <- fmts_na[[i]]() |
435 |
} |
|
436 | ||
437 | 1116x |
ret |
438 |
} |
|
439 | ||
440 |
summary_formats <- function(x, pcs, ne = NULL) { |
|
441 | 9192x |
assert_int(pcs, lower = 0, na.ok = TRUE) |
442 | 9192x |
switch(x, |
443 | 2284x |
n = h_format_dec(format = "%s", digits = pcs - pcs, ne = ne), |
444 |
min = , |
|
445 |
max = , |
|
446 | ! |
sum = h_format_dec(format = "%s", digits = pcs, ne = ne), |
447 |
mean = , |
|
448 |
sd = , |
|
449 |
median = , |
|
450 |
mad = , |
|
451 |
iqr = , |
|
452 |
cv = , |
|
453 |
geom_mean = , |
|
454 |
geom_cv = , |
|
455 | 2288x |
se = h_format_dec(format = "%s", digits = pcs + 1, ne = ne), |
456 |
mean_sd = , |
|
457 | 2284x |
mean_se = h_format_dec(format = "%s (%s)", digits = rep(pcs + 1, 2), ne = ne), |
458 |
mean_ci = , |
|
459 |
mean_sei = , |
|
460 |
median_ci = , |
|
461 | ! |
mean_sdi = h_format_dec(format = "(%s, %s)", digits = rep(pcs + 1, 2), ne = ne), |
462 | ! |
mean_pval = h_format_dec(format = "%s", digits = 2, ne = ne), |
463 | ! |
quantiles = h_format_dec(format = "(%s - %s)", digits = rep(pcs + 1, 2), ne = ne), |
464 | 2284x |
range = h_format_dec(format = "%s - %s", digits = rep(pcs, 2), ne = ne), |
465 | ! |
median_range = h_format_dec(format = "%s (%s - %s)", digits = c(pcs, pcs + 1, pcs + 1), ne = ne) |
466 |
) |
|
467 |
} |
|
468 | ||
469 |
#' Analyze with defined precision |
|
470 |
#' |
|
471 |
#' @param x value to analyze |
|
472 |
#' @param .var variable name. |
|
473 |
#' @param .spl_context split context. |
|
474 |
#' @param precision (named `list` of `integer`) where names of columns found in `.df_row` and the values indicate the |
|
475 |
#' number of digits in statistics for numeric value. If `default` is set, and parameter precision not specified, the |
|
476 |
#' value for `default` will be used. If neither are provided, auto determination is used. See [`tern::format_auto`]. |
|
477 |
#' @param .stats (named `list` of character) where names of columns found in `.df_row` and the values indicate the |
|
478 |
#' statistical analysis to perform. If `default` is set, and parameter precision not specified, the |
|
479 |
#' value for `default` will be used. |
|
480 |
#' @param .labels (`character`) See `tern::analyze_variables`. |
|
481 |
#' @param .indent_mods (`integer`) See `tern::analyze_variables`. |
|
482 |
#' @param .N_col (`int`) See `tern::analyze_variables`. |
|
483 |
#' @param .N_row (`int`) See `tern::analyze_variables`. |
|
484 |
#' @param ... additional arguments for `tern::a_summary`. |
|
485 |
#' |
|
486 |
#' @keywords internal |
|
487 |
afun_p <- function(x, |
|
488 |
.N_col, # nolint |
|
489 |
.spl_context, |
|
490 |
precision, |
|
491 |
.N_row, # nolint |
|
492 |
.var = NULL, |
|
493 |
.df_row = NULL, |
|
494 |
.stats = NULL, |
|
495 |
.labels = NULL, |
|
496 |
.indent_mods = NULL, |
|
497 |
...) { |
|
498 | 156x |
.stats <- .stats[[.var]] %||% .stats[["default"]] %||% c("n", "mean_sd", "median", "range", "count_fraction") |
499 | ||
500 |
# Define precision |
|
501 | 156x |
pcs <- precision[[.var]] %||% precision[["default"]] |
502 | 156x |
fmts <- if (is.null(pcs) && length(x) > 0) { |
503 | 100x |
lapply(.stats, function(.s) format_auto(dt_var = as.numeric(x), x_stat = .s)) |
504 |
} else { |
|
505 |
# Define an arbitrary precision if unavailable and unable to compute it. |
|
506 | 56x |
pcs <- pcs %||% 2 |
507 | 56x |
lapply(.stats, summary_formats, pcs = pcs, ne = NULL) |
508 |
} |
|
509 | 156x |
names(fmts) <- .stats |
510 | ||
511 | 152x |
if ("n" %in% .stats) fmts$n <- "xx" |
512 | 152x |
if ("count_fraction" %in% .stats) fmts$count_fraction <- format_count_fraction_fixed_dp |
513 | ||
514 | 156x |
tern::a_summary( |
515 | 156x |
.stats = .stats, .formats = fmts, .labels = .labels, .indent_mods = .indent_mods, |
516 | 156x |
x = x, .var = .var, .spl_context = .spl_context, .N_col = .N_col, .N_row = .N_row, ... |
517 |
) |
|
518 |
} |
|
519 | ||
520 |
split_fun_map <- function(map) { |
|
521 | 10x |
if (is.null(map)) { |
522 | 7x |
drop_split_levels |
523 |
} else { |
|
524 | 3x |
trim_levels_to_map(map = map) |
525 |
} |
|
526 |
} |
|
527 | ||
528 |
infer_mapping <- function(map_df, df) { |
|
529 | 3x |
assert_data_frame(df) |
530 | 3x |
vars <- colnames(map_df) |
531 | 3x |
assert_names(names(df), must.include = vars) |
532 | 3x |
for (x in vars) { |
533 | 7x |
if (!test_subset(map_df[[x]], lvls(df[[x]]))) { |
534 | ! |
rlang::abort( |
535 | ! |
paste0( |
536 | ! |
"Provided map should only contain valid levels in dataset in variable ", x, |
537 | ! |
". Consider convert ", x, " to factor first and add", |
538 | ! |
toString(setdiff(map_df[[x]], lvls(df[[x]]))), "levels to it." |
539 |
) |
|
540 |
) |
|
541 |
} |
|
542 |
} |
|
543 | 3x |
res <- df[vars] %>% |
544 | 3x |
unique() %>% |
545 | 3x |
arrange(across(everything())) %>% |
546 | 3x |
mutate(across(everything(), as.character)) |
547 | 3x |
if (!is.null(map_df)) { |
548 | 3x |
dplyr::full_join(map_df, res, by = colnames(map_df))[vars] |
549 |
} else { |
|
550 | ! |
res |
551 |
} |
|
552 |
} |
|
553 | ||
554 | ||
555 |
#' Occurrence Layout |
|
556 |
#' |
|
557 |
#' @inheritParams gen_args |
|
558 |
#' @inheritParams cmt01a_main |
|
559 |
#' @param lbl_medname_var (`string`) label for the variable defining the medication name. |
|
560 |
#' |
|
561 |
#' @keywords internal |
|
562 |
occurrence_lyt <- function(arm_var, |
|
563 |
lbl_overall, |
|
564 |
row_split_var, |
|
565 |
lbl_row_split, |
|
566 |
medname_var, |
|
567 |
lbl_medname_var, |
|
568 |
summary_labels, |
|
569 |
count_by) { |
|
570 | 24x |
split_indent <- vapply(c("TOTAL", row_split_var), function(x) { |
571 | ! |
if (length(summary_labels[[x]]) > 0L) -1L else 0L |
572 | 24x |
}, FUN.VALUE = 0L) |
573 | 24x |
split_indent[1L] <- 0L |
574 | 24x |
lyt <- basic_table(show_colcounts = TRUE) %>% |
575 | 24x |
split_cols_by_with_overall(arm_var, lbl_overall) |
576 | ||
577 | 24x |
if (length(summary_labels$TOTAL) > 0) { |
578 | 24x |
lyt <- lyt %>% |
579 | 24x |
analyze_num_patients( |
580 | 24x |
vars = "USUBJID", |
581 | 24x |
count_by = count_by, |
582 | 24x |
.stats = names(summary_labels$TOTAL), |
583 | 24x |
show_labels = "hidden", |
584 | 24x |
.labels = render_safe(summary_labels$TOTAL) |
585 |
) |
|
586 |
} |
|
587 | 24x |
section_divs <- get_section_div() |
588 | 24x |
for (k in seq_len(length(row_split_var))) { |
589 | 21x |
lyt <- split_and_summ_num_patients( |
590 | 21x |
lyt = lyt, |
591 | 21x |
count_by = count_by, |
592 | 21x |
var = row_split_var[k], |
593 | 21x |
label = lbl_row_split[k], |
594 | 21x |
split_indent = split_indent[k], |
595 | 21x |
stats = names(summary_labels[[row_split_var[k]]]), |
596 | 21x |
summarize_labels = render_safe(summary_labels[[row_split_var[k]]]), |
597 | 21x |
section_div = section_divs[k] |
598 |
) |
|
599 |
} |
|
600 | ||
601 | 24x |
lyt %>% |
602 | 24x |
count_occurrences( |
603 | 24x |
vars = medname_var, |
604 | 24x |
drop = length(row_split_var) > 0, |
605 | 24x |
.indent_mods = unname(tail(split_indent, 1L)) |
606 |
) %>% |
|
607 | 24x |
append_topleft(paste0(stringr::str_dup(" ", 2 * length(row_split_var)), lbl_medname_var)) |
608 |
} |
1 |
# aet03 ---- |
|
2 | ||
3 |
#' @describeIn aet03 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @returns the main function returns an `rtables` object. |
|
7 |
#' |
|
8 |
#' @details |
|
9 |
#' * Default Adverse Events by Greatest Intensity table. |
|
10 |
#' * Numbers represent absolute numbers of patients and fraction of `N`. |
|
11 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
12 |
#' * Split columns by arm. |
|
13 |
#' * Does not include a total column by default. |
|
14 |
#' * Sort by Body System or Organ Class (`SOC`) and Dictionary-Derived Term (`PT`). |
|
15 |
#' |
|
16 |
#' @note |
|
17 |
#' * `adam_db` object must contain an `adae` table with the columns `"AEBODSYS"`, `"AEDECOD"` and `"ASEV"`. |
|
18 |
#' |
|
19 |
#' @export |
|
20 |
#' |
|
21 |
aet03_main <- function(adam_db, |
|
22 |
arm_var = "ACTARM", |
|
23 |
lbl_overall = NULL, |
|
24 |
...) { |
|
25 | 1x |
assert_all_tablenames(adam_db, "adsl", "adae") |
26 | 1x |
assert_string(arm_var) |
27 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
28 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
29 | 1x |
assert_valid_variable(adam_db$adae, c(arm_var, "AEBODSYS", "AEDECOD", "ASEV"), types = list(c("character", "factor"))) |
30 | 1x |
assert_valid_variable(adam_db$adae, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
31 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adae, arm_var) |
32 | ||
33 | 1x |
lbl_overall <- render_safe(lbl_overall) |
34 | 1x |
lbl_aebodsys <- var_labels_for(adam_db$adae, "AEBODSYS") |
35 | 1x |
lbl_aedecod <- var_labels_for(adam_db$adae, "AEDECOD") |
36 | 1x |
intensity_grade <- levels(adam_db$adae[["ASEV"]]) |
37 | ||
38 | 1x |
lyt <- aet03_lyt( |
39 | 1x |
arm_var = arm_var, |
40 | 1x |
lbl_overall = lbl_overall, |
41 | 1x |
lbl_aebodsys = lbl_aebodsys, |
42 | 1x |
lbl_aedecod = lbl_aedecod, |
43 | 1x |
intensity_grade = intensity_grade |
44 |
) |
|
45 | ||
46 | 1x |
tbl <- build_table(lyt, df = adam_db$adae, alt_counts_df = adam_db$adsl) |
47 | ||
48 | 1x |
tbl |
49 |
} |
|
50 | ||
51 |
#' `aet03` Layout |
|
52 |
#' |
|
53 |
#' @inheritParams gen_args |
|
54 |
#' |
|
55 |
#' @param lbl_aebodsys (`string`) text label for `AEBODSYS`. |
|
56 |
#' @param lbl_aedecod (`string`) text label for `AEDECOD`. |
|
57 |
#' @param intensity_grade (`character`) describing the intensity levels present in the dataset. |
|
58 |
#' @returns a `PreDataTableLayouts` object. |
|
59 |
#' @keywords internal |
|
60 |
#' |
|
61 |
aet03_lyt <- function(arm_var, |
|
62 |
lbl_overall, |
|
63 |
lbl_aebodsys, |
|
64 |
lbl_aedecod, |
|
65 |
intensity_grade) { |
|
66 | 4x |
all_grade_groups <- list("- Any Intensity -" = intensity_grade) |
67 | ||
68 | 4x |
basic_table(show_colcounts = TRUE) %>% |
69 | 4x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
70 | 4x |
count_occurrences_by_grade( |
71 | 4x |
var = "ASEV", |
72 | 4x |
grade_groups = all_grade_groups, |
73 | 4x |
.formats = c("count_fraction" = format_count_fraction_fixed_dp) |
74 |
) %>% |
|
75 | 4x |
split_rows_by( |
76 | 4x |
"AEBODSYS", |
77 | 4x |
child_labels = "visible", |
78 | 4x |
nested = TRUE, |
79 | 4x |
split_fun = drop_split_levels, |
80 | 4x |
label_pos = "topleft", |
81 | 4x |
split_label = lbl_aebodsys |
82 |
) %>% |
|
83 | 4x |
summarize_occurrences_by_grade( |
84 | 4x |
var = "ASEV", |
85 | 4x |
grade_groups = all_grade_groups, |
86 | 4x |
.formats = c("count_fraction" = format_count_fraction_fixed_dp) |
87 |
) %>% |
|
88 | 4x |
split_rows_by( |
89 | 4x |
"AEDECOD", |
90 | 4x |
child_labels = "visible", |
91 | 4x |
nested = TRUE, |
92 | 4x |
indent_mod = -1L, |
93 | 4x |
split_fun = drop_split_levels, |
94 | 4x |
label_pos = "topleft", |
95 | 4x |
split_label = lbl_aedecod |
96 |
) %>% |
|
97 | 4x |
summarize_num_patients( |
98 | 4x |
var = "USUBJID", |
99 | 4x |
.stats = "unique", |
100 | 4x |
.labels = c("- Any Intensity -") |
101 |
) %>% |
|
102 | 4x |
count_occurrences_by_grade( |
103 | 4x |
var = "ASEV", |
104 | 4x |
.indent_mods = -1L |
105 |
) |
|
106 |
} |
|
107 | ||
108 |
#' @describeIn aet03 Preprocessing |
|
109 |
#' |
|
110 |
#' @inheritParams gen_args |
|
111 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
112 |
#' @export |
|
113 |
#' |
|
114 |
aet03_pre <- function(adam_db, ...) { |
|
115 | 1x |
asev_lvls <- c("MILD", "MODERATE", "SEVERE") |
116 | 1x |
adam_db$adae <- adam_db$adae %>% |
117 | 1x |
filter(.data$ANL01FL == "Y") %>% |
118 | 1x |
mutate( |
119 | 1x |
AEBODSYS = reformat(.data$AEBODSYS, nocoding), |
120 | 1x |
AEDECOD = reformat(.data$AEDECOD, nocoding), |
121 | 1x |
ASEV = factor(.data$ASEV, levels = asev_lvls) |
122 |
) %>% |
|
123 | 1x |
filter(!is.na(.data$ASEV)) |
124 | ||
125 | 1x |
adam_db |
126 |
} |
|
127 | ||
128 |
#' @describeIn aet03 Postprocessing |
|
129 |
#' |
|
130 |
#' @inheritParams gen_args |
|
131 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
132 |
#' @export |
|
133 |
#' |
|
134 |
aet03_post <- function(tlg, prune_0 = TRUE, ...) { |
|
135 | 1x |
tlg <- tlg %>% |
136 | 1x |
tlg_sort_by_vars( |
137 | 1x |
c("AEBODSYS", "AEDECOD"), |
138 | 1x |
scorefun = cont_n_allcols |
139 |
) |
|
140 | 1x |
if (prune_0) tlg <- trim_rows(tlg) |
141 | 1x |
std_postprocessing(tlg) |
142 |
} |
|
143 | ||
144 |
#' `AET03` Table 1 (Default) Advert Events by Greatest Intensity Table 1. |
|
145 |
#' |
|
146 |
#' An adverse events table categorized by System |
|
147 |
#' Organ Class, Dictionary-Derived Term and Greatest intensity. |
|
148 |
#' |
|
149 |
#' @include chevron_tlg-S4class.R |
|
150 |
#' @export |
|
151 |
#' |
|
152 |
#' @examples |
|
153 |
#' run(aet03, syn_data) |
|
154 |
aet03 <- chevron_t( |
|
155 |
main = aet03_main, |
|
156 |
preprocess = aet03_pre, |
|
157 |
postprocess = aet03_post |
|
158 |
) |
1 |
# assert_single_value ---- |
|
2 | ||
3 |
#' Check variable only has one unique value. |
|
4 |
#' @param x value vector. |
|
5 |
#' @param label (`string`) label of input. |
|
6 |
#' @returns invisible `NULL` or an error message if the criteria are not fulfilled. |
|
7 |
#' @export |
|
8 |
assert_single_value <- function(x, label = deparse(substitute(x))) { |
|
9 | 68x |
unique_param_val <- unique(x) |
10 | 68x |
if (length(unique_param_val) > 1) { |
11 | ! |
stop( |
12 | ! |
quote_str(label), |
13 | ! |
" has more than one values ", |
14 | ! |
toString(unique_param_val), |
15 | ! |
", only one value is allowed." |
16 |
) |
|
17 |
} |
|
18 |
} |
|
19 | ||
20 |
# assert_valid_var ---- |
|
21 | ||
22 |
#' @title Check whether var is valid |
|
23 |
#' @details |
|
24 |
#' This function checks the variable values are valid or not. |
|
25 |
#' @param x value of col_split variable |
|
26 |
#' @param label (`string`) hints. |
|
27 |
#' @param na_ok (`flag`) whether NA value is allowed |
|
28 |
#' @param empty_ok (`flag`) whether length 0 value is allowed. |
|
29 |
#' @param ... Further arguments to methods. |
|
30 |
#' @returns invisible `NULL` or an error message if the criteria are not fulfilled. |
|
31 |
#' @export |
|
32 |
assert_valid_var <- function(x, label, na_ok, empty_ok, ...) { |
|
33 | 1931x |
UseMethod("assert_valid_var") |
34 |
} |
|
35 |
#' @rdname assert_valid_var |
|
36 |
#' @export |
|
37 |
#' @param min_chars (`integer`) the minimum length of the characters. |
|
38 |
assert_valid_var.character <- function( |
|
39 |
x, label = deparse(substitute(x)), |
|
40 |
na_ok = FALSE, empty_ok = FALSE, |
|
41 |
min_chars = 1L, ...) { |
|
42 | 462x |
assert_character( |
43 | 462x |
x, |
44 | 462x |
min.chars = min_chars, |
45 | 462x |
min.len = as.integer(!empty_ok), |
46 | 462x |
any.missing = na_ok, |
47 | 462x |
.var.name = label, |
48 |
... |
|
49 |
) |
|
50 |
} |
|
51 | ||
52 |
#' @rdname assert_valid_var |
|
53 |
#' @export |
|
54 |
assert_valid_var.factor <- function( |
|
55 |
x, label = deparse(substitute(x)), |
|
56 |
na_ok = FALSE, empty_ok = FALSE, |
|
57 |
min_chars = 1L, ...) { |
|
58 | 1080x |
assert_character( |
59 | 1080x |
levels(x), |
60 | 1080x |
min.chars = min_chars, |
61 | 1080x |
.var.name = paste("level of", label) |
62 |
) |
|
63 | 1079x |
assert_factor( |
64 | 1079x |
x, |
65 | 1079x |
min.levels = as.integer(!empty_ok), |
66 | 1079x |
any.missing = na_ok, |
67 | 1079x |
.var.name = label, |
68 |
... |
|
69 |
) |
|
70 |
} |
|
71 | ||
72 |
#' @rdname assert_valid_var |
|
73 |
#' @export |
|
74 |
assert_valid_var.logical <- function(x, label = deparse(substitute(x)), na_ok = TRUE, empty_ok = FALSE, ...) { |
|
75 | 191x |
assert_logical( |
76 | 191x |
x, |
77 | 191x |
min.len = as.integer(!empty_ok), |
78 | 191x |
any.missing = na_ok, |
79 | 191x |
.var.name = label, |
80 |
... |
|
81 |
) |
|
82 |
} |
|
83 | ||
84 |
#' @rdname assert_valid_var |
|
85 |
#' @param integerish (`flag`) whether the number should be treated as `integerish`. |
|
86 |
#' @export |
|
87 |
assert_valid_var.numeric <- function( |
|
88 |
x, label = deparse(substitute(x)), |
|
89 |
na_ok = TRUE, empty_ok = FALSE, integerish = FALSE, ...) { |
|
90 | 190x |
check_fun <- if (integerish) assert_integerish else assert_numeric |
91 | 190x |
check_fun( |
92 | 190x |
x, |
93 | 190x |
min.len = as.integer(!empty_ok), |
94 | 190x |
any.missing = na_ok, |
95 | 190x |
.var.name = label, |
96 |
... |
|
97 |
) |
|
98 |
} |
|
99 | ||
100 |
#' @rdname assert_valid_var |
|
101 |
#' @param tzs (`character`) time zones. |
|
102 |
#' @export |
|
103 |
assert_valid_var.POSIXct <- function(x, |
|
104 |
label = deparse(substitute(x)), |
|
105 |
na_ok = TRUE, |
|
106 |
empty_ok = FALSE, |
|
107 |
tzs = OlsonNames(), |
|
108 |
...) { |
|
109 | 8x |
assert_posixct( |
110 | 8x |
x, |
111 | 8x |
min.len = as.integer(!empty_ok), |
112 | 8x |
any.missing = na_ok, |
113 | 8x |
.var.name = label, |
114 |
... |
|
115 |
) |
|
116 | ||
117 | 8x |
extra_args <- list(...) |
118 | ||
119 |
# Test if time zone of x is in OlsonNames |
|
120 | 8x |
if (lubridate::tz(x) %in% tzs) { |
121 | 7x |
return(invisible(NULL)) |
122 | 1x |
} else if (is(extra_args$add, "AssertCollection")) { |
123 | ! |
extra_args$add$push(paste("Non standard timezone detected for", label, "!")) |
124 |
} else { |
|
125 | 1x |
abort(paste("Non standard timezone detected for", label, "!")) |
126 |
} |
|
127 |
} |
|
128 | ||
129 |
#' @rdname assert_valid_var |
|
130 |
#' @export |
|
131 |
assert_valid_var.default <- function(x, label = deparse(substitute(x)), na_ok = FALSE, empty_ok = FALSE, ...) { |
|
132 |
} |
|
133 | ||
134 |
# assert_valid_variable ---- |
|
135 | ||
136 |
#' Check variables in a data frame are valid character or factor. |
|
137 |
#' @param df (`data.frame`) input dataset. |
|
138 |
#' @param vars (`character`) variables to check. |
|
139 |
#' @param label (`string`) labels of the data frame. |
|
140 |
#' @param types Named (`list`) of type of the input. |
|
141 |
#' @param ... further arguments for `assert_valid_var`. Please note that different methods have different arguments |
|
142 |
#' so if provided make sure the variables to check is of the same class. |
|
143 |
#' @returns invisible `TRUE` or an error message if the criteria are not fulfilled. |
|
144 |
#' @export |
|
145 |
assert_valid_variable <- function(df, vars, label = deparse(substitute(df)), types = NULL, ...) { |
|
146 | 1113x |
assert_names(colnames(df), must.include = vars, what = "colnames") |
147 | ||
148 | 1109x |
labels <- sprintf("%s$%s", label, vars) |
149 | 1109x |
if (length(types) == 1 && is.null(names(types))) { |
150 | 980x |
types <- setNames(rep(types, length(vars)), vars) |
151 |
} |
|
152 | 1109x |
if (!is.null(types)) { |
153 | 1024x |
vars_to_check <- which(vars %in% names(types)) |
154 | 1024x |
mapply( |
155 | 1024x |
assert_valid_type, |
156 | 1024x |
df[vars[vars_to_check]], |
157 | 1024x |
types = types[vars_to_check], |
158 | 1024x |
label = labels[vars_to_check] |
159 |
) |
|
160 |
} |
|
161 | 1106x |
collection <- makeAssertCollection() |
162 | 1106x |
mapply(assert_valid_var, df[vars], labels, MoreArgs = list(..., add = collection), SIMPLIFY = FALSE) |
163 | 1106x |
reportAssertions(collection) |
164 |
} |
|
165 | ||
166 |
# assert_valid_type ---- |
|
167 | ||
168 |
#' Check variable is of correct type |
|
169 |
#' @param x Object to check the type. |
|
170 |
#' @param types (`character`) possible types to check. |
|
171 |
#' @param label (`string`) label. |
|
172 |
#' @returns invisible `NULL` or an error message if the criteria are not fulfilled. |
|
173 |
assert_valid_type <- function(x, types, label = deparse(substitute(x))) { |
|
174 | 1584x |
if (!any(vapply(types, is, object = x, FUN.VALUE = TRUE))) { |
175 | 3x |
abort( |
176 | 3x |
paste0( |
177 | 3x |
quote_str(label), |
178 | 3x |
" is not of type ", |
179 | 3x |
toString(types) |
180 |
) |
|
181 |
) |
|
182 |
} |
|
183 |
} |
|
184 | ||
185 |
# assert_valid_var_pair ---- |
|
186 | ||
187 |
#' Check variables are of same levels |
|
188 |
#' @param df1 (`data.frame`) input. |
|
189 |
#' @param df2 (`data.frame`) input. |
|
190 |
#' @param var (`string`) variable to check. |
|
191 |
#' @param lab1 (`string`) label hint for `df1`. |
|
192 |
#' @param lab2 (`string`) label hint for `df2`. |
|
193 |
#' @returns invisible `NULL` or an error message if the criteria are not fulfilled. |
|
194 |
assert_valid_var_pair <- function(df1, df2, var, lab1 = deparse(substitute(df1)), lab2 = deparse(substitute(df2))) { |
|
195 | 175x |
assert_data_frame(df1) |
196 | 175x |
assert_data_frame(df2) |
197 | 175x |
assert_string(var) |
198 | 175x |
lvl_x <- lvls(df1[[var]]) |
199 | 175x |
lvl_y <- lvls(df2[[var]]) |
200 | 175x |
if (!identical(lvl_x, lvl_y)) { |
201 | 3x |
abort( |
202 | 3x |
paste0( |
203 | 3x |
quote_str(lab1), " and ", |
204 | 3x |
quote_str(lab2), " should contain the same levels in variable ", |
205 | 3x |
quote_str(var), "!" |
206 |
) |
|
207 |
) |
|
208 |
} |
|
209 |
} |
1 |
# cmt01a ---- |
|
2 | ||
3 |
#' @describeIn cmt01a Default labels |
|
4 |
#' @export |
|
5 |
#' |
|
6 |
cmt01_label <- c( |
|
7 |
unique = "Total number of {patient_label} with at least one treatment", |
|
8 |
nonunique = "Total number of treatments" |
|
9 |
) |
|
10 | ||
11 |
#' @describeIn cmt01a Main TLG function |
|
12 |
#' |
|
13 |
#' @inheritParams gen_args |
|
14 |
#' @param row_split_var (`character`) the variable defining the medication category. By default `ATC2`. |
|
15 |
#' @param medname_var (`string`) variable name of medical treatment name. |
|
16 |
#' @param summary_labels (`list`) of summarize labels. See details. |
|
17 |
#' @returns the main function returns an `rtables` object. |
|
18 |
#' |
|
19 |
#' @details |
|
20 |
#' * Data should be filtered for concomitant medication. `(ATIREL == "CONCOMITANT")`. |
|
21 |
#' * Numbers represent absolute numbers of subjects and fraction of `N`, or absolute numbers when specified. |
|
22 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
23 |
#' * Split columns by arm. |
|
24 |
#' * Does not include a total column by default. |
|
25 |
#' * Sort by medication class alphabetically and within medication class by decreasing total number of patients with |
|
26 |
#' the specific medication. |
|
27 |
#' `summary_labels` is used to control the summary for each level. If "all" is used, then each split will have that |
|
28 |
#' summary statistic with the labels. One special case is "TOTAL", this is for the overall population. |
|
29 |
#' |
|
30 |
#' @note |
|
31 |
#' * `adam_db` object must contain an `adcm` table with the columns specified in `row_split_var` and `medname_var` |
|
32 |
#' as well as `"CMSEQ"`. |
|
33 |
#' |
|
34 |
#' @export |
|
35 |
#' |
|
36 |
cmt01a_main <- function(adam_db, |
|
37 |
arm_var = "ARM", |
|
38 |
lbl_overall = NULL, |
|
39 |
row_split_var = "ATC2", |
|
40 |
medname_var = "CMDECOD", |
|
41 |
summary_labels = setNames( |
|
42 |
rep(list(cmt01_label), length(row_split_var) + 1L), c("TOTAL", row_split_var) |
|
43 |
), |
|
44 |
...) { |
|
45 | 3x |
assert_all_tablenames(adam_db, "adsl", "adcm") |
46 | 3x |
assert_string(arm_var) |
47 | 3x |
assert_string(lbl_overall, null.ok = TRUE) |
48 | 3x |
assert_character(row_split_var, null.ok = TRUE) |
49 | 3x |
assert_list(summary_labels) |
50 | 3x |
assert_subset(names(summary_labels), c("all", "TOTAL", row_split_var)) |
51 | 3x |
assert_subset( |
52 | 3x |
unique(unlist(lapply(summary_labels, names))), |
53 | 3x |
c("unique", "nonunique", "unique_count") |
54 |
) |
|
55 | 3x |
summary_labels <- expand_list(summary_labels, c("TOTAL", row_split_var)) |
56 | 3x |
assert_valid_variable(adam_db$adcm, c(arm_var, row_split_var, medname_var), types = list(c("character", "factor"))) |
57 | 3x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
58 | 3x |
assert_valid_variable(adam_db$adcm, c("USUBJID", "CMSEQ"), empty_ok = TRUE, types = list(c("character", "factor"))) |
59 | 3x |
assert_valid_var_pair(adam_db$adsl, adam_db$adcm, arm_var) |
60 | ||
61 | 3x |
lbl_overall <- render_safe(lbl_overall) |
62 | 3x |
lbl_row_split <- var_labels_for(adam_db$adcm, row_split_var) |
63 | 3x |
lbl_medname_var <- var_labels_for(adam_db$adcm, medname_var) |
64 | ||
65 | 3x |
lyt <- occurrence_lyt( |
66 | 3x |
arm_var = arm_var, |
67 | 3x |
lbl_overall = lbl_overall, |
68 | 3x |
row_split_var = row_split_var, |
69 | 3x |
lbl_row_split = lbl_row_split, |
70 | 3x |
medname_var = medname_var, |
71 | 3x |
lbl_medname_var = lbl_medname_var, |
72 | 3x |
summary_labels = summary_labels, |
73 | 3x |
count_by = "CMSEQ" |
74 |
) |
|
75 | ||
76 | 3x |
tbl <- build_table(lyt, adam_db$adcm, alt_counts_df = adam_db$adsl) |
77 | ||
78 | 3x |
tbl |
79 |
} |
|
80 | ||
81 |
#' @describeIn cmt01a Preprocessing |
|
82 |
#' |
|
83 |
#' @inheritParams cmt01a_main |
|
84 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
85 |
#' @export |
|
86 |
#' |
|
87 |
cmt01a_pre <- function(adam_db, ...) { |
|
88 | 3x |
adam_db$adcm <- adam_db$adcm %>% |
89 | 3x |
filter(.data$ANL01FL == "Y") %>% |
90 | 3x |
mutate( |
91 | 3x |
CMDECOD = with_label(reformat(.data$CMDECOD, nocoding), "Other Treatment"), |
92 | 3x |
ATC2 = reformat(.data$ATC2, nocoding), |
93 | 3x |
CMSEQ = as.character(.data$CMSEQ) |
94 |
) |
|
95 | 3x |
adam_db |
96 |
} |
|
97 | ||
98 |
#' @describeIn cmt01a Postprocessing |
|
99 |
#' |
|
100 |
#' @inheritParams cmt01a_main |
|
101 |
#' @inheritParams gen_args |
|
102 |
#' @param sort_by_freq (`flag`) whether to sort medication class by frequency. |
|
103 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
104 |
#' @export |
|
105 |
#' |
|
106 |
cmt01a_post <- function( |
|
107 |
tlg, prune_0 = TRUE, |
|
108 |
sort_by_freq = FALSE, row_split_var = "ATC2", |
|
109 |
medname_var = "CMDECOD", ...) { |
|
110 | 3x |
if (sort_by_freq) { |
111 | 1x |
tlg <- tlg %>% |
112 | 1x |
tlg_sort_by_var( |
113 | 1x |
var = row_split_var, |
114 | 1x |
scorefun = cont_n_allcols |
115 |
) |
|
116 |
} |
|
117 | 3x |
tlg <- tlg %>% |
118 | 3x |
tlg_sort_by_var( |
119 | 3x |
var = c(row_split_var, medname_var), |
120 | 3x |
scorefun = score_occurrences |
121 |
) |
|
122 | 3x |
if (prune_0) { |
123 | 3x |
tlg <- smart_prune(tlg) |
124 |
} |
|
125 | 3x |
std_postprocessing(tlg) |
126 |
} |
|
127 | ||
128 |
#' `CMT01A` Concomitant Medication by Medication Class and Preferred Name. |
|
129 |
#' |
|
130 |
#' A concomitant medication |
|
131 |
#' table with the number of subjects and the total number of treatments by medication class. |
|
132 |
#' |
|
133 |
#' @include chevron_tlg-S4class.R |
|
134 |
#' @export |
|
135 |
#' |
|
136 |
#' @examples |
|
137 |
#' library(dplyr) |
|
138 |
#' |
|
139 |
#' proc_data <- syn_data |
|
140 |
#' proc_data$adcm <- proc_data$adcm %>% |
|
141 |
#' filter(ATIREL == "CONCOMITANT") |
|
142 |
#' |
|
143 |
#' run(cmt01a, proc_data) |
|
144 |
cmt01a <- chevron_t( |
|
145 |
main = cmt01a_main, |
|
146 |
preprocess = cmt01a_pre, |
|
147 |
postprocess = cmt01a_post |
|
148 |
) |
1 |
# lbt04 ---- |
|
2 | ||
3 |
#' @describeIn lbt04 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param analysis_abn_var (`string`) column describing anomaly magnitude |
|
7 |
#' @param baseline_abn_var (`string`) column describing anomaly at baseline. |
|
8 |
#' @returns the main function returns an `rtables` object. |
|
9 |
#' |
|
10 |
#' @details |
|
11 |
#' * Only count LOW or HIGH values. |
|
12 |
#' * Lab test results with missing `analysis_abn_var` values are excluded. |
|
13 |
#' * Split columns by arm, typically `ACTARM`. |
|
14 |
#' * Does not include a total column by default. |
|
15 |
#' |
|
16 |
#' @note |
|
17 |
#' * `adam_db` object must contain an `adlb` table with columns `"PARCAT1"`, `"PARCAT2"`, `"PARAM"`, `"ANRIND"`, |
|
18 |
#' and column specified by `arm_var`. |
|
19 |
#' |
|
20 |
#' @export |
|
21 |
#' |
|
22 |
lbt04_main <- function(adam_db, |
|
23 |
arm_var = "ACTARM", |
|
24 |
lbl_overall = NULL, |
|
25 |
analysis_abn_var = "ANRIND", |
|
26 |
baseline_abn_var = "BNRIND", |
|
27 |
row_split_var = "PARCAT1", |
|
28 |
page_var = tail(row_split_var, 1L), |
|
29 |
...) { |
|
30 | 2x |
assert_all_tablenames(adam_db, c("adsl", "adlb")) |
31 | 2x |
assert_string(arm_var) |
32 | 2x |
assert_string(lbl_overall, null.ok = TRUE) |
33 | 2x |
assert_string(analysis_abn_var) |
34 | 2x |
assert_string(baseline_abn_var) |
35 | 2x |
assert_string(row_split_var) |
36 | 2x |
assert_valid_variable( |
37 | 2x |
adam_db$adlb, c("PARAMCD", "PARAM", row_split_var), |
38 | 2x |
types = list("characater", "factor") |
39 |
) |
|
40 | 2x |
assert_subset(page_var, row_split_var) |
41 | 2x |
assert_valid_variable(adam_db$adlb, c("USUBJID"), types = list(c("character", "factor")), empty_ok = TRUE) |
42 | 2x |
assert_valid_variable(adam_db$adsl, c("USUBJID"), types = list(c("character", "factor"))) |
43 | 2x |
assert_valid_variable( |
44 | 2x |
adam_db$adlb, |
45 | 2x |
baseline_abn_var, |
46 | 2x |
types = list(c("character", "factor")), |
47 | 2x |
na_ok = TRUE, empty_ok = TRUE, min_chars = 0L |
48 |
) |
|
49 | 2x |
assert_valid_var_pair(adam_db$adsl, adam_db$adlb, arm_var) |
50 | ||
51 | 2x |
lbl_overall <- render_safe(lbl_overall) |
52 | 2x |
lbl_param <- var_labels_for(adam_db$adlb, "PARAM") |
53 | 2x |
lbl_abn_var <- var_labels_for(adam_db$adlb, analysis_abn_var) |
54 | 2x |
row_split_lbl <- var_labels_for(adam_db$adlb, row_split_var) |
55 | ||
56 | 2x |
lyt <- lbt04_lyt( |
57 | 2x |
arm_var = arm_var, |
58 | 2x |
lbl_overall = lbl_overall, |
59 | 2x |
lbl_param = lbl_param, |
60 | 2x |
lbl_abn_var = lbl_abn_var, |
61 | 2x |
var_parcat = "PARCAT1", |
62 | 2x |
var_param = "PARAM", |
63 | 2x |
row_split_var = row_split_var, |
64 | 2x |
row_split_lbl = row_split_lbl, |
65 | 2x |
analysis_abn_var = analysis_abn_var, |
66 | 2x |
variables = list(id = "USUBJID", baseline = baseline_abn_var), |
67 | 2x |
page_var = page_var |
68 |
) |
|
69 | ||
70 | 2x |
tbl <- build_table(lyt, adam_db$adlb, alt_counts_df = adam_db$adsl) |
71 | ||
72 | 2x |
tbl |
73 |
} |
|
74 | ||
75 |
#' `lbt04` Layout |
|
76 |
#' |
|
77 |
#' @inheritParams gen_args |
|
78 |
#' |
|
79 |
#' @param lbl_param (`string`) label of the `PARAM` variable. |
|
80 |
#' @param lbl_abn_var (`string`) label of the `analysis_abn_var` variable. |
|
81 |
#' @param variables (`list`) see [tern::count_abnormal] |
|
82 |
#' |
|
83 |
#' @keywords internal |
|
84 |
#' |
|
85 |
lbt04_lyt <- function(arm_var, |
|
86 |
lbl_overall, |
|
87 |
lbl_param, |
|
88 |
lbl_abn_var, |
|
89 |
var_parcat, |
|
90 |
var_param, |
|
91 |
row_split_var, |
|
92 |
row_split_lbl, |
|
93 |
analysis_abn_var, |
|
94 |
variables, |
|
95 |
page_var) { |
|
96 | 10x |
page_by <- get_page_by(page_var, row_split_var) |
97 | 10x |
label_pos <- ifelse(page_by, "hidden", "topleft") |
98 | ||
99 | 10x |
basic_table(show_colcounts = TRUE) %>% |
100 | 10x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
101 | 10x |
split_rows_by_recursive( |
102 | 10x |
row_split_var, |
103 | 10x |
split_label = row_split_lbl, |
104 | 10x |
label_pos = label_pos, |
105 | 10x |
page_by = page_by |
106 |
) %>% |
|
107 | 10x |
split_rows_by( |
108 | 10x |
"PARAMCD", |
109 | 10x |
labels_var = "PARAM", |
110 | 10x |
split_fun = drop_split_levels, |
111 | 10x |
label_pos = "topleft", |
112 | 10x |
split_label = lbl_param, |
113 | 10x |
indent_mod = 0L |
114 |
) %>% |
|
115 | 10x |
count_abnormal( |
116 | 10x |
var = analysis_abn_var, |
117 | 10x |
abnormal = list(Low = c("LOW", "LOW LOW"), High = c("HIGH", "HIGH HIGH")), |
118 | 10x |
exclude_base_abn = TRUE, |
119 | 10x |
variables = variables, |
120 | 10x |
.formats = list(fraction = format_fraction_fixed_dp) |
121 |
) %>% |
|
122 | 10x |
append_topleft(paste(" ", lbl_abn_var)) |
123 |
} |
|
124 | ||
125 |
#' @describeIn lbt04 Preprocessing |
|
126 |
#' |
|
127 |
#' @inheritParams gen_args |
|
128 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
129 |
#' @export |
|
130 |
#' |
|
131 |
lbt04_pre <- function(adam_db, ...) { |
|
132 | 1x |
adam_db$adlb <- adam_db$adlb %>% |
133 | 1x |
filter( |
134 | 1x |
.data$ONTRTFL == "Y", |
135 | 1x |
.data$PARCAT2 == "SI", |
136 | 1x |
!is.na(.data$ANRIND) |
137 |
) %>% |
|
138 | 1x |
mutate( |
139 | 1x |
PARAM = with_label(.data$PARAM, "Laboratory Test"), |
140 | 1x |
ANRIND = with_label(.data$ANRIND, "Direction of Abnormality") |
141 |
) %>% |
|
142 | 1x |
mutate( |
143 | 1x |
ANRIND = reformat( |
144 | 1x |
.data$ANRIND, |
145 | 1x |
rule( |
146 | 1x |
"HIGH HIGH" = "HIGH HIGH", |
147 | 1x |
"HIGH" = "HIGH", |
148 | 1x |
"LOW" = "LOW", |
149 | 1x |
"LOW LOW" = "LOW LOW", |
150 | 1x |
"NORMAL" = "NORMAL" |
151 |
), |
|
152 | 1x |
.to_NA = NULL |
153 |
) |
|
154 |
) |
|
155 | ||
156 | 1x |
adam_db |
157 |
} |
|
158 | ||
159 |
#' @describeIn lbt04 Postprocessing |
|
160 |
#' |
|
161 |
#' @inheritParams gen_args |
|
162 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
163 |
#' @export |
|
164 |
#' |
|
165 |
lbt04_post <- function(tlg, ...) { |
|
166 | 2x |
std_postprocessing(tlg) |
167 |
} |
|
168 | ||
169 |
#' `LBT04` Laboratory Abnormalities Not Present at Baseline Table. |
|
170 |
#' |
|
171 |
#' The `LBT04` table provides an |
|
172 |
#' overview of laboratory abnormalities not present at baseline. |
|
173 |
#' |
|
174 |
#' @include chevron_tlg-S4class.R |
|
175 |
#' @export |
|
176 |
#' |
|
177 |
#' @examples |
|
178 |
#' run(lbt04, syn_data) |
|
179 |
lbt04 <- chevron_t( |
|
180 |
main = lbt04_main, |
|
181 |
preprocess = lbt04_pre, |
|
182 |
postprocess = lbt04_post |
|
183 |
) |
1 |
# dst01 ---- |
|
2 | ||
3 |
#' @describeIn dst01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param arm_var (`string`) variable. Usually one of `ARM`, `ACTARM`, `TRT01A`, or `TRT01A`. |
|
7 |
#' @param study_status_var (`string`) variable used to define patient status. Default is `EOSSTT`, however can also be a |
|
8 |
#' variable name with the pattern `EOPxxSTT` where `xx` must be substituted by 2 digits referring to the analysis |
|
9 |
#' period. |
|
10 |
#' @param detail_vars Named (`list`) of grouped display of `study_status_var`. The names must be subset of unique levels |
|
11 |
#' of `study_status_var`. |
|
12 |
#' @param trt_status_var (`string`) variable of treatment status. |
|
13 |
#' @returns the main function returns an `rtables` object. |
|
14 |
#' @details |
|
15 |
#' * Default patient disposition table summarizing the reasons for patients withdrawal. |
|
16 |
#' * Numbers represent absolute numbers of patients and fraction of `N`. |
|
17 |
#' * Remove zero-count rows. |
|
18 |
#' * Split columns by arm. |
|
19 |
#' * Include a total column by default. |
|
20 |
#' * Sort withdrawal reasons by alphabetic order. |
|
21 |
#' |
|
22 |
#' @note |
|
23 |
#' * `adam_db` object must contain an `adsl` table with the columns specified by `status_var` and `disc_reason_var`. |
|
24 |
#' |
|
25 |
#' @export |
|
26 |
#' |
|
27 |
dst01_main <- function(adam_db, |
|
28 |
arm_var = "ARM", |
|
29 |
lbl_overall = "All {Patient_label}", |
|
30 |
study_status_var = "EOSSTT", |
|
31 |
detail_vars = list( |
|
32 |
Discontinued = c("DCSREAS") |
|
33 |
), |
|
34 |
trt_status_var = NULL, |
|
35 |
...) { |
|
36 | 1x |
assert_all_tablenames(adam_db, "adsl") |
37 | 1x |
assert_string(arm_var) |
38 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
39 | 1x |
assert_string(study_status_var) |
40 | 1x |
assert_list(detail_vars, types = "character", names = "unique") |
41 | 1x |
assert_string(trt_status_var, null.ok = TRUE) |
42 | 1x |
assert_valid_variable( |
43 | 1x |
adam_db$adsl, |
44 | 1x |
arm_var, |
45 | 1x |
types = list(c("character", "factor")), na_ok = TRUE |
46 |
) |
|
47 | 1x |
assert_valid_variable( |
48 | 1x |
adam_db$adsl, study_status_var, |
49 | 1x |
types = list(c("character", "factor")), na_ok = TRUE, |
50 | 1x |
empty_ok = FALSE, min_chars = 1L |
51 |
) |
|
52 | 1x |
status_var_lvls <- lvls(adam_db$adsl[[study_status_var]]) |
53 | 1x |
assert_subset(names(detail_vars), choices = status_var_lvls) |
54 | 1x |
assert_valid_variable( |
55 | 1x |
adam_db$adsl, |
56 | 1x |
unlist(detail_vars), |
57 | 1x |
types = list(c("character", "factor")), |
58 | 1x |
na_ok = TRUE, |
59 | 1x |
empty_ok = TRUE, |
60 | 1x |
min_chars = 0L |
61 |
) |
|
62 | 1x |
assert_valid_variable( |
63 | 1x |
adam_db$adsl, trt_status_var, |
64 | 1x |
types = list(c("character", "factor")), na_ok = TRUE, |
65 | 1x |
empty_ok = TRUE, min_chars = 0L |
66 |
) |
|
67 | ||
68 | 1x |
lbl_overall <- render_safe(lbl_overall) |
69 | 1x |
detail_vars <- setNames(detail_vars[status_var_lvls], status_var_lvls) |
70 | ||
71 | 1x |
lyt <- dst01_lyt( |
72 | 1x |
arm_var = arm_var, |
73 | 1x |
lbl_overall = lbl_overall, |
74 | 1x |
study_status_var = study_status_var, |
75 | 1x |
detail_vars = detail_vars, |
76 | 1x |
trt_status_var = trt_status_var |
77 |
) |
|
78 | 1x |
build_table(lyt, adam_db$adsl) |
79 |
} |
|
80 | ||
81 |
#' `dst01` Layout |
|
82 |
#' |
|
83 |
#' @inheritParams dst01_main |
|
84 |
#' @param study_status_var (`string`) variable used to define patient status. Default is `EOSSTT`, however can also be a |
|
85 |
#' variable name with the pattern `EOPxxSTT` where `xx` must be substituted by 2 digits referring to the analysis |
|
86 |
#' period. |
|
87 |
#' @param detail_vars Named (`list`) of grouped display of `study_status_var`. |
|
88 |
#' @returns a `PreDataTableLayouts` object. |
|
89 |
#' @keywords internal |
|
90 |
#' |
|
91 |
dst01_lyt <- function(arm_var, |
|
92 |
lbl_overall, |
|
93 |
study_status_var, |
|
94 |
detail_vars, |
|
95 |
trt_status_var) { |
|
96 | 9x |
lyt <- basic_table(show_colcounts = TRUE) %>% |
97 | 9x |
split_cols_by_with_overall(arm_var, lbl_overall) |
98 | ||
99 | 9x |
for (n in names(detail_vars)) { |
100 | 27x |
lyt <- lyt %>% |
101 | 27x |
count_or_summarize(study_status_var, n, detail_vars[[n]]) |
102 |
} |
|
103 | ||
104 | 9x |
if (!is.null(trt_status_var)) { |
105 | 1x |
lyt <- lyt %>% |
106 | 1x |
analyze_vars( |
107 | 1x |
trt_status_var, |
108 | 1x |
.stats = "count_fraction", |
109 | 1x |
denom = "N_col", |
110 | 1x |
.formats = list(count_fraction = format_count_fraction_fixed_dp), |
111 | 1x |
show_labels = "hidden", |
112 | 1x |
nested = FALSE |
113 |
) |
|
114 |
} |
|
115 | ||
116 | 9x |
lyt |
117 |
} |
|
118 | ||
119 |
#' @describeIn dst01 Preprocessing |
|
120 |
#' |
|
121 |
#' @inheritParams dst01_main |
|
122 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
123 |
#' @export |
|
124 |
#' |
|
125 |
dst01_pre <- function(adam_db, |
|
126 |
...) { |
|
127 | 1x |
study_status_format <- rule( |
128 | 1x |
"Completed" = "COMPLETED", |
129 | 1x |
"Ongoing" = "ONGOING", |
130 | 1x |
"Discontinued" = "DISCONTINUED" |
131 |
) |
|
132 | 1x |
trt_status_format <- rule( |
133 | 1x |
"Completed Treatment" = "COMPLETED", |
134 | 1x |
"Ongoing Treatment" = "ONGOING", |
135 | 1x |
"Discontinued Treatment" = "DISCONTINUED" |
136 |
) |
|
137 | 1x |
dcsreas_grp_format <- rule( |
138 | 1x |
"Safety" = c("ADVERSE EVENT", "DEATH"), |
139 | 1x |
"Non-Safety" = c( |
140 | 1x |
"WITHDRAWAL BY SUBJECT", "LACK OF EFFICACY", "PROTOCOL VIOLATION", |
141 | 1x |
"WITHDRAWAL BY PARENT/GUARDIAN", "PHYSICIAN DECISION" |
142 |
) |
|
143 |
) |
|
144 | 1x |
adam_db$adsl <- adam_db$adsl %>% |
145 | 1x |
mutate( |
146 | 1x |
EOSSTT = reformat(.data$EOSSTT, study_status_format), |
147 | 1x |
EOTSTT = reformat(.data$EOTSTT, trt_status_format), |
148 | 1x |
DCSREASGP = reformat(.data$DCSREAS, dcsreas_grp_format), |
149 | 1x |
DCSREAS = reformat(.data$DCSREAS, empty_rule), |
150 | 1x |
STDONS = factor( |
151 | 1x |
case_when( |
152 | 1x |
EOTSTT == "Ongoing Treatment" & EOSSTT == "Ongoing" ~ "Alive: Ongoing", |
153 | 1x |
EOTSTT != "Ongoing Treatment" & EOSSTT == "Ongoing" ~ "Alive: In Follow-up", |
154 | 1x |
TRUE ~ NA_character_ |
155 |
), |
|
156 | 1x |
levels = c("Alive: Ongoing", "Alive: In Follow-up") |
157 |
) |
|
158 |
) |
|
159 | 1x |
adam_db |
160 |
} |
|
161 | ||
162 |
#' @describeIn dst01 Postprocessing |
|
163 |
#' |
|
164 |
#' @inheritParams gen_args |
|
165 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
166 |
#' @export |
|
167 |
#' |
|
168 |
dst01_post <- function(tlg, prune_0 = TRUE, ...) { |
|
169 | 1x |
if (prune_0) { |
170 | 1x |
tlg <- tlg %>% |
171 | 1x |
smart_prune() |
172 |
} |
|
173 | 1x |
std_postprocessing(tlg) |
174 |
} |
|
175 | ||
176 |
#' DST01 Table 1 (Default) Patient Disposition Table 1. |
|
177 |
#' |
|
178 |
#' The DST01 Disposition Table provides an overview of patients |
|
179 |
#' study completion. For patients who discontinued the study a reason is provided. |
|
180 |
#' |
|
181 |
#' @include chevron_tlg-S4class.R |
|
182 |
#' @export |
|
183 |
#' |
|
184 |
#' @examples |
|
185 |
#' run(dst01, syn_data, detail_vars = list(Ongoing = "STDONS")) |
|
186 |
#' |
|
187 |
#' run(dst01, syn_data, detail_vars = list(Discontinued = "DCSREAS", Ongoing = "STDONS")) |
|
188 |
#' |
|
189 |
#' run( |
|
190 |
#' dst01, syn_data, |
|
191 |
#' detail_vars = list( |
|
192 |
#' Discontinued = c("DCSREASGP", "DCSREAS"), |
|
193 |
#' Ongoing = "STDONS" |
|
194 |
#' ) |
|
195 |
#' ) |
|
196 |
dst01 <- chevron_t( |
|
197 |
main = dst01_main, |
|
198 |
preprocess = dst01_pre, |
|
199 |
postprocess = dst01_post |
|
200 |
) |
1 |
#' @include chevron_tlg-S4class.R |
|
2 | ||
3 |
# run ---- |
|
4 | ||
5 |
#' Run the pipeline |
|
6 |
#' |
|
7 |
#' Execute the pre-processing, main and post-processing functions in a single run. |
|
8 |
#' |
|
9 |
#' @inheritParams gen_args |
|
10 |
#' @param object (`chevron_tlg`) input. |
|
11 |
#' @param auto_pre (`flag`) whether to perform the default pre processing step. |
|
12 |
#' @param verbose (`flag`) whether to print argument information. |
|
13 |
#' @param ... extra arguments to pass to the pre-processing, main and post-processing functions. |
|
14 |
#' @param user_args (`list`) arguments from `...`. |
|
15 |
#' @returns an `rtables` (for `chevron_t`), `rlistings` (for `chevron_l`), `grob` (for `chevron_g`) or `ElementaryTable` |
|
16 |
#' (null report) depending on the class of `chevron_tlg` object passed as `object` argument. |
|
17 |
#' |
|
18 |
#' @name run |
|
19 |
#' @export |
|
20 |
setGeneric( |
|
21 |
"run", |
|
22 | 230x |
function(object, adam_db, auto_pre = TRUE, verbose = FALSE, ..., user_args = list(...)) standardGeneric("run") |
23 |
) |
|
24 | ||
25 |
#' Run the pipeline |
|
26 |
#' @rdname run |
|
27 |
#' @export |
|
28 |
#' @examples |
|
29 |
#' run(mng01, syn_data, auto_pre = TRUE, dataset = "adlb") |
|
30 |
setMethod( |
|
31 |
f = "run", |
|
32 |
signature = "chevron_tlg", |
|
33 |
definition = function(object, adam_db, auto_pre = TRUE, verbose = FALSE, ..., user_args = list(...)) { |
|
34 | 230x |
assert_list(adam_db, types = "data.frame", names = "unique") |
35 | 230x |
assert_flag(auto_pre) |
36 | 230x |
assert_flag(verbose) |
37 | 230x |
assert_list(user_args, names = "unique") |
38 | 230x |
args <- list(...) |
39 | 230x |
assert_list(args, names = "unique", .var.name = "...") |
40 | 230x |
additional_names <- setdiff(names(user_args), names(args)) |
41 | 230x |
user_args <- modifyList(user_args, args, keep.null = TRUE) |
42 | ||
43 | 230x |
if (verbose) { |
44 | 6x |
cl <- match.call() |
45 | 6x |
print_args( |
46 | 6x |
run_call = cl, |
47 | 6x |
additional_args = user_args[additional_names], |
48 | 6x |
args = args_ls(object, omit = c("...", "adam_db", "tlg")), |
49 | 6x |
auto_pre = auto_pre |
50 |
) |
|
51 |
} |
|
52 | 230x |
proc_data <- if (auto_pre) { |
53 | 229x |
list(adam_db = do_call(object@preprocess, c(list(adam_db), user_args))) |
54 |
} else { |
|
55 | 1x |
list(adam_db = adam_db) |
56 |
} |
|
57 | ||
58 | 217x |
res_tlg <- list(tlg = do_call(object@main, c(proc_data, user_args))) |
59 | ||
60 | 208x |
do_call(object@postprocess, c(res_tlg, user_args)) |
61 |
} |
|
62 |
) |
|
63 | ||
64 |
#' Print Arguments |
|
65 |
#' @keywords internal |
|
66 |
print_args <- function(run_call, additional_args, args, auto_pre = TRUE) { |
|
67 | 6x |
assert_class(run_call, "call") |
68 | 6x |
assert_list(args) |
69 | 6x |
assert_flag(auto_pre) |
70 | ||
71 | 6x |
run_call[[1]] <- NULL |
72 | 6x |
run_call <- as.list(run_call) |
73 | ||
74 | 6x |
run_call[c("auto_pre", "verbose", "user_args")] <- NULL |
75 | 6x |
if (!is.null(additional_args)) { |
76 | 6x |
run_call <- c(run_call, additional_args) |
77 |
} |
|
78 | 6x |
nms_args <- unique(unlist(lapply(args, names))) |
79 | 6x |
nms_call <- names(run_call) |
80 | 6x |
m <- pmatch(nms_call, nms_args) |
81 | 6x |
nms_call[!is.na(m)] <- nms_args[m[!is.na(m)]] |
82 | 6x |
names(run_call) <- nms_call |
83 | 6x |
cat( |
84 | 6x |
"Using template: ", |
85 | 6x |
if (is.name(run_call$object)) run_call$object else paste("object of class", class(run_call$object)), |
86 | 6x |
"\n" |
87 |
) |
|
88 | 6x |
cat( |
89 | 6x |
"Using data: ", |
90 | 6x |
if (is.name(run_call$adam_db)) run_call$adam_db else paste("object of class", class(run_call$adam_db)), |
91 | 6x |
"\n" |
92 |
) |
|
93 | 6x |
if (auto_pre) { |
94 | 6x |
cat("\nPre args:\n") |
95 | 6x |
print_list(get_subset(args$preprocess, run_call)) |
96 |
} |
|
97 | 6x |
cat("\nMain args:\n") |
98 | 6x |
print_list(get_subset(args$main, run_call)) |
99 | 6x |
cat("\nPost args:\n") |
100 | 6x |
print_list(get_subset(args$postprocess, run_call)) |
101 | 6x |
add_args <- run_call[ |
102 | 6x |
!names(run_call) %in% c(names(args$main), names(args$postprocess), names(args$preprocess), "object", "adam_db") |
103 |
] |
|
104 | 6x |
if (length(add_args) > 0) { |
105 | 3x |
cat("\nAdditional args:\n") |
106 | 3x |
print_list(add_args) |
107 |
} |
|
108 | 6x |
cat("\n\n") |
109 |
} |
|
110 | ||
111 |
#' Subset Arguments and Merge |
|
112 |
#' @keywords internal |
|
113 |
get_subset <- function(x, y) { |
|
114 | 18x |
utils::modifyList( |
115 | 18x |
x, |
116 | 18x |
y[names(y) %in% names(x)], |
117 | 18x |
keep.null = TRUE |
118 |
) |
|
119 |
} |
|
120 | ||
121 |
#' Print list |
|
122 |
#' @keywords internal |
|
123 |
print_list <- function(x, indent = 2L) { |
|
124 | 23x |
if (length(x) == 0) { |
125 | 2x |
cat(paste0( |
126 | 2x |
stringr::str_dup(" ", indent), |
127 | 2x |
"No mapped argument.\n" |
128 |
)) |
|
129 | 2x |
return() |
130 |
} |
|
131 | 21x |
k <- names(x) |
132 | 21x |
m_charx <- max(nchar(k), 1) |
133 | 21x |
for (k in names(x)) { |
134 | 47x |
cat( |
135 | 47x |
sprintf( |
136 | 47x |
paste0("%s%-", m_charx + 2, "s: %s\n"), |
137 | 47x |
stringr::str_dup(" ", indent), k, |
138 | 47x |
deparse_print(x[[k]], m_charx + indent + 2) |
139 |
) |
|
140 |
) |
|
141 |
} |
|
142 |
} |
|
143 | ||
144 |
#' Deparse print |
|
145 |
#' @keywords internal |
|
146 |
deparse_print <- function(x, indent, max_line = getOption("chevron.arg_max_line", 5L)) { |
|
147 | 47x |
assert_int(indent) |
148 | 47x |
assert_int(max_line, lower = 1L) |
149 | 47x |
ret <- deparse(x) |
150 | 47x |
sep <- paste0("\n", stringr::str_dup(" ", indent)) |
151 | 47x |
if (length(ret) > max_line) { |
152 | 2x |
ret[max_line] <- sprintf("... (print of class <%s> truncated)", toString(class(x))) |
153 | 2x |
ret <- ret[seq_len(max_line)] |
154 |
} |
|
155 | 47x |
paste(ret, collapse = sep) |
156 |
} |
|
157 | ||
158 |
# args_ls ---- |
|
159 | ||
160 |
#' Get Arguments List |
|
161 |
#' |
|
162 |
#' @param x (`chevron_tlg`) input. |
|
163 |
#' @param simplify (`flag`) whether to simplify the output, coalescing the values of the parameters. The order of |
|
164 |
#' priority for the value of the parameters is: `main`, `preprocess` and `postprocess`. |
|
165 |
#' @param omit (`character`) the names of the argument to omit from the output. |
|
166 |
#' @returns a `list` of the formal arguments with their default for the functions stored in the `chevron_tlg` object |
|
167 |
#' passed a `x` argument. |
|
168 |
#' |
|
169 |
#' @rdname args_ls |
|
170 |
#' @export |
|
171 |
#' @examples |
|
172 |
#' args_ls(aet01, simplify = TRUE) |
|
173 | 9x |
setGeneric("args_ls", function(x, simplify = FALSE, omit = NULL) standardGeneric("args_ls")) |
174 | ||
175 |
#' @rdname args_ls |
|
176 |
#' @export |
|
177 |
setMethod( |
|
178 |
f = "args_ls", |
|
179 |
signature = "chevron_tlg", |
|
180 |
definition = function(x, simplify = FALSE, omit = NULL) { |
|
181 | 9x |
assert_flag(simplify) |
182 | 9x |
assert_character(omit, null.ok = TRUE) |
183 | ||
184 | 9x |
x_ls <- list( |
185 | 9x |
main = formals(x@main), |
186 | 9x |
preprocess = formals(x@preprocess), |
187 | 9x |
postprocess = formals(x@postprocess) |
188 |
) |
|
189 | ||
190 | 9x |
x_sel <- lapply(x_ls, function(y) y[!names(y) %in% omit]) |
191 | ||
192 | 9x |
res <- if (simplify) { |
193 | 2x |
Reduce(fuse_sequentially, x_sel) |
194 |
} else { |
|
195 | 7x |
x_sel |
196 |
} |
|
197 | ||
198 | 9x |
res |
199 |
} |
|
200 |
) |
|
201 | ||
202 |
# main ---- |
|
203 | ||
204 |
#' Main |
|
205 |
#' |
|
206 |
#' retrieve or set `main` function. |
|
207 |
#' |
|
208 |
#' @param x (`chevron_tlg`) input. |
|
209 |
#' @returns the `function` stored in the `main` slot of the `x` argument. |
|
210 |
#' |
|
211 |
#' @aliases main |
|
212 |
#' @export |
|
213 | 1x |
setGeneric("main", function(x) standardGeneric("main")) |
214 | ||
215 |
#' @rdname main |
|
216 |
#' @export |
|
217 |
setMethod( |
|
218 |
f = "main", |
|
219 |
signature = "chevron_tlg", |
|
220 |
definition = function(x) { |
|
221 | 1x |
x@main |
222 |
} |
|
223 |
) |
|
224 | ||
225 |
#' Set Main Function |
|
226 |
#' |
|
227 |
#' @param x (`chevron_tlg`) input. |
|
228 |
#' @param value (`function`) returning a `tlg`. Typically one of the `_main` function of `chevron`. |
|
229 |
#' |
|
230 |
#' @rdname main |
|
231 |
#' @export |
|
232 | 5x |
setGeneric("main<-", function(x, value) standardGeneric("main<-")) |
233 | ||
234 |
#' @rdname main |
|
235 |
#' @export |
|
236 |
setMethod( |
|
237 |
f = "main<-", |
|
238 |
signature = "chevron_tlg", |
|
239 |
definition = function(x, value) { |
|
240 | 5x |
x@main <- value |
241 | 5x |
validObject(x) |
242 | 3x |
x |
243 |
} |
|
244 |
) |
|
245 | ||
246 |
# preprocess ---- |
|
247 | ||
248 |
#' Pre process |
|
249 |
#' |
|
250 |
#' retrieve or set `preprocess` function. |
|
251 |
#' |
|
252 |
#' @param x (`chevron_tlg`) input. |
|
253 |
#' |
|
254 |
#' @aliases preprocess |
|
255 |
#' @export |
|
256 | 2x |
setGeneric("preprocess", function(x) standardGeneric("preprocess")) |
257 | ||
258 |
#' @rdname preprocess |
|
259 |
#' @export |
|
260 |
setMethod( |
|
261 |
f = "preprocess", |
|
262 |
signature = "chevron_tlg", |
|
263 |
definition = function(x) { |
|
264 | 2x |
x@preprocess |
265 |
} |
|
266 |
) |
|
267 | ||
268 |
#' Set Preprocess Function |
|
269 |
#' |
|
270 |
#' @param x (`chevron_tlg`) input. |
|
271 |
#' @param value (`function`) returning a pre-processed `list` of `data.frames` amenable to `tlg` creation. Typically |
|
272 |
#' one of the `_pre` function of `chevron`. |
|
273 |
#' @returns the `function` stored in the `preprocess` slot of the `x` argument. |
|
274 |
#' |
|
275 |
#' @rdname preprocess |
|
276 |
#' @export |
|
277 | 4x |
setGeneric("preprocess<-", function(x, value) standardGeneric("preprocess<-")) |
278 | ||
279 |
#' @rdname preprocess |
|
280 |
#' @export |
|
281 |
setMethod( |
|
282 |
f = "preprocess<-", |
|
283 |
signature = "chevron_tlg", |
|
284 |
definition = function(x, value) { |
|
285 | 4x |
x@preprocess <- value |
286 | 4x |
validObject(x) |
287 | 3x |
x |
288 |
} |
|
289 |
) |
|
290 | ||
291 |
# postprocess ---- |
|
292 | ||
293 |
#' Post process |
|
294 |
#' |
|
295 |
#' retrieve or set `postprocess` function. |
|
296 |
#' |
|
297 |
#' @param x (`chevron_tlg`) input. |
|
298 |
#' @returns the `function` stored in the `postprocess` slot of the `x` argument. |
|
299 |
#' |
|
300 |
#' @aliases postprocess |
|
301 |
#' @export |
|
302 | 1x |
setGeneric("postprocess", function(x) standardGeneric("postprocess")) |
303 | ||
304 |
#' @rdname postprocess |
|
305 |
#' @export |
|
306 |
setMethod( |
|
307 |
f = "postprocess", |
|
308 |
signature = "chevron_tlg", |
|
309 |
definition = function(x) { |
|
310 | 1x |
x@postprocess |
311 |
} |
|
312 |
) |
|
313 | ||
314 |
#' Postprocess Assignment Function |
|
315 |
#' |
|
316 |
#' @param x (`chevron_tlg`) input. |
|
317 |
#' @param value (`function`) returning a post-processed `tlg`. |
|
318 |
#' |
|
319 |
#' @rdname postprocess |
|
320 |
#' @export |
|
321 | 2x |
setGeneric("postprocess<-", function(x, value) standardGeneric("postprocess<-")) |
322 | ||
323 |
#' @rdname postprocess |
|
324 |
#' @export |
|
325 |
setMethod( |
|
326 |
f = "postprocess<-", |
|
327 |
signature = "chevron_tlg", |
|
328 |
definition = function(x, value) { |
|
329 | 2x |
x@postprocess <- value |
330 | 2x |
validObject(x) |
331 | 1x |
x |
332 |
} |
|
333 |
) |
|
334 | ||
335 |
# script ---- |
|
336 | ||
337 |
#' Create Script for `TLG` Generation |
|
338 |
#' |
|
339 |
#' @param x (`chevron_tlg`) input. |
|
340 |
#' @param adam_db (`string`) the name of the dataset. |
|
341 |
#' @param name (`string`) name of the template. |
|
342 |
#' @param args (`string`) the name of argument list. |
|
343 |
#' @returns `character` that can be integrated into an executable script. |
|
344 |
#' |
|
345 |
#' @name script |
|
346 |
#' @rdname script |
|
347 |
NULL |
|
348 | ||
349 |
#' @rdname script |
|
350 |
#' @export |
|
351 | 3x |
setGeneric("script_funs", function(x, adam_db, args, name = deparse(substitute(x))) standardGeneric("script_funs")) |
352 | ||
353 |
#' @rdname script |
|
354 |
#' @export |
|
355 |
#' |
|
356 |
#' @examples |
|
357 |
#' script_funs(aet04, adam_db = "syn_data", args = "args") |
|
358 |
setMethod( |
|
359 |
f = "script_funs", |
|
360 |
signature = "chevron_tlg", |
|
361 |
definition = function(x, adam_db, args, name) { |
|
362 | 2x |
checkmate::assert_string(adam_db) |
363 | 2x |
checkmate::assert_string(args) |
364 | 2x |
checkmate::assert_string(name) |
365 | 2x |
c( |
366 | 2x |
"# Edit Preprocessing Function.", |
367 | 2x |
glue::glue("preprocess({name}) <- "), |
368 | 2x |
deparse(preprocess(x)), |
369 |
"", |
|
370 | 2x |
"# Create TLG", |
371 | 2x |
glue::glue( |
372 | 2x |
"tlg_output <- run(object = {name}, adam_db = {adam_db}", |
373 | 2x |
", verbose = TRUE, user_args = {args})" |
374 |
) |
|
375 |
) |
|
376 |
} |
|
377 |
) |
|
378 | ||
379 |
#' @rdname script |
|
380 |
#' @export |
|
381 |
#' |
|
382 |
setMethod( |
|
383 |
f = "script_funs", |
|
384 |
signature = "chevron_simple", |
|
385 |
definition = function(x, adam_db, args, name) { |
|
386 | 1x |
checkmate::assert_string(adam_db) |
387 | 1x |
main_body <- body(main(x)) |
388 | 1x |
c( |
389 | 1x |
"# Create TLG", |
390 | 1x |
if (!identical(adam_db, "adam_db")) { |
391 | 1x |
glue::glue("adam_db <- {adam_db}") |
392 |
}, |
|
393 |
"", |
|
394 | 1x |
"tlg_output <- ", |
395 | 1x |
deparse(main_body) |
396 |
) |
|
397 |
} |
|
398 |
) |
1 |
# vst02_1 ---- |
|
2 | ||
3 |
#' @describeIn vst02_1 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param exclude_base_abn (`flag`) whether baseline abnormality should be excluded. |
|
7 |
#' @returns the main function returns an `rtables` object. |
|
8 |
#' |
|
9 |
#' @details |
|
10 |
#' * Only count LOW or HIGH values. |
|
11 |
#' * Results of "LOW LOW" are treated as the same as "LOW", and "HIGH HIGH" the same as "HIGH". |
|
12 |
#' * Does not include a total column by default. |
|
13 |
#' * Does not remove zero-count rows unless overridden with `prune_0 = TRUE`. |
|
14 |
#' |
|
15 |
#' @note |
|
16 |
#' * `adam_db` object must contain an `advs` table with the `"PARAM"`, `"ANRIND"` and `"BNRIND"` columns. |
|
17 |
#' |
|
18 |
#' @export |
|
19 |
#' |
|
20 |
vst02_1_main <- function(adam_db, |
|
21 |
arm_var = "ACTARM", |
|
22 |
lbl_overall = NULL, |
|
23 |
exclude_base_abn = FALSE, |
|
24 |
...) { |
|
25 | 2x |
assert_all_tablenames(adam_db, "adsl", "advs") |
26 | 2x |
assert_string(arm_var) |
27 | 2x |
assert_string(lbl_overall, null.ok = TRUE) |
28 | 2x |
assert_flag(exclude_base_abn) |
29 | 2x |
assert_valid_variable(adam_db$advs, c(arm_var, "PARAM", "ANRIND", "BNRIND"), types = list(c("character", "factor"))) |
30 | 2x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
31 | 2x |
assert_valid_variable(adam_db$advs, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
32 | 2x |
assert_valid_var_pair(adam_db$adsl, adam_db$advs, arm_var) |
33 | ||
34 | 2x |
lbl_overall <- render_safe(lbl_overall) |
35 | 2x |
lbl_vs_assessment <- var_labels_for(adam_db$advs, "PARAM") |
36 | 2x |
lbl_vs_abnormality <- var_labels_for(adam_db$advs, "ANRIND") |
37 | ||
38 | 2x |
lyt <- vst02_lyt( |
39 | 2x |
arm_var = arm_var, |
40 | 2x |
lbl_overall = lbl_overall, |
41 | 2x |
exclude_base_abn = exclude_base_abn, |
42 | 2x |
lbl_vs_assessment = lbl_vs_assessment, |
43 | 2x |
lbl_vs_abnormality = lbl_vs_abnormality |
44 |
) |
|
45 | ||
46 | 2x |
tbl <- build_table(lyt, adam_db$advs, alt_counts_df = adam_db$adsl) |
47 | ||
48 | 2x |
tbl |
49 |
} |
|
50 | ||
51 |
#' `vst02_1` Layout |
|
52 |
#' |
|
53 |
#' @inheritParams gen_args |
|
54 |
#' @param lbl_vs_assessment (`string`) the label of the assessment variable. |
|
55 |
#' @param lbl_vs_abnormality (`string`) the label of the abnormality variable. |
|
56 |
#' @param exclude_base_abn (`flag`) whether to exclude subjects with baseline abnormality from numerator and |
|
57 |
#' denominator. |
|
58 |
#' |
|
59 |
#' @keywords internal |
|
60 |
#' |
|
61 |
vst02_lyt <- function(arm_var, |
|
62 |
lbl_overall, |
|
63 |
exclude_base_abn, |
|
64 |
lbl_vs_assessment, |
|
65 |
lbl_vs_abnormality) { |
|
66 | 4x |
basic_table(show_colcounts = TRUE) %>% |
67 | 4x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
68 | 4x |
split_rows_by("PARAM", split_fun = drop_split_levels, label_pos = "topleft", split_label = lbl_vs_assessment) %>% |
69 | 4x |
count_abnormal( |
70 | 4x |
"ANRIND", |
71 | 4x |
abnormal = list(Low = "LOW", High = "HIGH"), |
72 | 4x |
variables = list(id = "USUBJID", baseline = "BNRIND"), |
73 | 4x |
exclude_base_abn = exclude_base_abn |
74 |
) %>% |
|
75 | 4x |
append_topleft(paste0(" ", lbl_vs_abnormality)) |
76 |
} |
|
77 | ||
78 |
#' @describeIn vst02_1 Preprocessing |
|
79 |
#' |
|
80 |
#' @inheritParams gen_args |
|
81 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
82 |
#' @export |
|
83 |
#' |
|
84 |
vst02_pre <- function(adam_db, ...) { |
|
85 | 2x |
high_low_format <- rule( |
86 | 2x |
HIGH = c("HIGH HIGH", "HIGH"), |
87 | 2x |
LOW = c("LOW LOW", "LOW") |
88 |
) |
|
89 | ||
90 | 2x |
adam_db$advs <- adam_db$advs %>% |
91 | 2x |
filter(.data$ONTRTFL == "Y") %>% |
92 | 2x |
mutate( |
93 | 2x |
PARAM = with_label(.data$PARAM, "Assessment"), |
94 | 2x |
ANRIND = with_label(reformat(.data$ANRIND, high_low_format), "Abnormality"), |
95 | 2x |
BNRIND = reformat(.data$BNRIND, high_low_format) |
96 |
) |
|
97 | ||
98 | 2x |
adam_db |
99 |
} |
|
100 | ||
101 |
#' @describeIn vst02_1 Postprocessing |
|
102 |
#' |
|
103 |
#' @inheritParams gen_args |
|
104 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
105 |
#' @export |
|
106 |
#' |
|
107 |
vst02_post <- function(tlg, prune_0 = FALSE, ...) { |
|
108 | 2x |
if (prune_0) { |
109 | ! |
tlg <- smart_prune(tlg) |
110 |
} |
|
111 | 2x |
std_postprocessing(tlg) |
112 |
} |
|
113 | ||
114 |
#' `VST02` Vital Sign Abnormalities Table. |
|
115 |
#' |
|
116 |
#' Vital Sign Parameters outside Normal Limits Regardless of Abnormality at Baseline. |
|
117 |
#' |
|
118 |
#' @include chevron_tlg-S4class.R |
|
119 |
#' @export |
|
120 |
#' |
|
121 |
#' @examples |
|
122 |
#' run(vst02_1, syn_data) |
|
123 |
vst02_1 <- chevron_t( |
|
124 |
main = vst02_1_main, |
|
125 |
preprocess = vst02_pre, |
|
126 |
postprocess = vst02_post |
|
127 |
) |
|
128 | ||
129 |
# vst02_2 ---- |
|
130 | ||
131 |
#' @describeIn vst02_2 Main TLG function |
|
132 |
#' |
|
133 |
#' @inherit vst02_1_main |
|
134 |
#' |
|
135 |
#' @export |
|
136 |
#' |
|
137 |
vst02_2_main <- modify_default_args(vst02_1_main, exclude_base_abn = TRUE) |
|
138 |
#' `VST02` Vital Sign Abnormalities Table. |
|
139 |
#' |
|
140 |
#' Vital Sign Parameters outside Normal Limits Among Patients without Abnormality at Baseline. |
|
141 |
#' |
|
142 |
#' @include chevron_tlg-S4class.R |
|
143 |
#' @export |
|
144 |
#' |
|
145 |
#' @examples |
|
146 |
#' run(vst02_2, syn_data) |
|
147 |
vst02_2 <- chevron_t( |
|
148 |
main = vst02_2_main, |
|
149 |
preprocess = vst02_pre, |
|
150 |
postprocess = vst02_post |
|
151 |
) |
1 |
# aet01 ---- |
|
2 | ||
3 |
#' @describeIn aet01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param anl_vars Named (`list`) of (`character`) variables the safety variables to be summarized. |
|
7 |
#' @param show_wd (`flag`) whether to display the number of patients withdrawn from study due to an adverse event and |
|
8 |
#' the number of death. |
|
9 |
#' @param anl_lbls (`character`) of analysis labels. |
|
10 |
#' @returns the main function returns an `rtables` object. |
|
11 |
#' |
|
12 |
#' @details |
|
13 |
#' * Does not remove rows with zero counts by default. |
|
14 |
#' |
|
15 |
#' @note |
|
16 |
#' * `adam_db` object must contain an `adsl` table with the `"DTHFL"` and `"DCSREAS"` columns. |
|
17 |
#' * `adam_db` object must contain an `adae` table with the columns passed to `anl_vars`. |
|
18 |
#' |
|
19 |
#' @export |
|
20 |
#' |
|
21 |
aet01_main <- function(adam_db, |
|
22 |
arm_var = "ACTARM", |
|
23 |
lbl_overall = NULL, |
|
24 |
anl_vars = list( |
|
25 |
safety_var = c( |
|
26 |
"FATAL", "SER", "SERWD", "SERDSM", |
|
27 |
"RELSER", "WD", "DSM", "REL", "RELWD", "RELDSM", "SEV" |
|
28 |
) |
|
29 |
), |
|
30 |
anl_lbls = "Total number of {patient_label} with at least one", |
|
31 |
show_wd = TRUE, |
|
32 |
...) { |
|
33 | 1x |
assert_all_tablenames(adam_db, "adsl", "adae") |
34 | 1x |
assert_string(arm_var) |
35 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
36 | 1x |
assert_list(anl_vars, types = "character", names = "unique") |
37 | 1x |
assert_character(anl_lbls, min.chars = 1L) |
38 | 1x |
assert_flag(show_wd) |
39 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor")), empty_ok = TRUE) |
40 | 1x |
assert_valid_variable( |
41 | 1x |
adam_db$adsl, |
42 | 1x |
c("DTHFL", "DCSREAS"), |
43 | 1x |
types = list(c("character", "factor")), |
44 | 1x |
min_chars = 0L, empty_ok = TRUE |
45 |
) |
|
46 | 1x |
assert_valid_variable(adam_db$adae, c(arm_var), types = list(c("character", "factor"))) |
47 | 1x |
assert_valid_variable(adam_db$adae, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
48 | 1x |
assert_valid_variable(adam_db$adae, unlist(anl_vars), types = list("logical"), na_ok = TRUE, empty_ok = TRUE) |
49 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adae, arm_var) |
50 | ||
51 | 1x |
lbl_overall <- render_safe(lbl_overall) |
52 | 1x |
anl_lbls <- render_safe(anl_lbls) |
53 | 1x |
if (length(anl_lbls) == 1) { |
54 | 1x |
anl_lbls <- rep(anl_lbls, length(anl_vars)) |
55 |
} |
|
56 | 1x |
lbl_vars <- lapply( |
57 | 1x |
anl_vars, |
58 | 1x |
var_labels_for, |
59 | 1x |
df = adam_db$adae |
60 |
) |
|
61 | ||
62 | 1x |
lyts <- aet01_lyt( |
63 | 1x |
arm_var = arm_var, |
64 | 1x |
lbl_overall = lbl_overall, |
65 | 1x |
anl_vars = anl_vars, |
66 | 1x |
anl_lbls = anl_lbls, |
67 | 1x |
lbl_vars = lbl_vars |
68 |
) |
|
69 | ||
70 | 1x |
if (show_wd) { |
71 | 1x |
rbind( |
72 | 1x |
build_table(lyts$ae1, adam_db$adae, alt_counts_df = adam_db$adsl), |
73 | 1x |
build_table(lyts$adsl, adam_db$adsl, alt_counts_df = adam_db$adsl), |
74 | 1x |
build_table(lyts$ae2, adam_db$adae, alt_counts_df = adam_db$adsl) |
75 |
) |
|
76 |
} else { |
|
77 | ! |
rbind( |
78 | ! |
build_table(lyts$ae1, adam_db$adae, alt_counts_df = adam_db$adsl), |
79 | ! |
build_table(lyts$ae2, adam_db$adae, alt_counts_df = adam_db$adsl) |
80 |
) |
|
81 |
} |
|
82 |
} |
|
83 | ||
84 |
#' `aet01` Layout |
|
85 |
#' |
|
86 |
#' @inheritParams aet01_main |
|
87 |
#' @param anl_vars Named (`list`) of analysis variables. |
|
88 |
#' @param anl_lbls (`character`) of labels. |
|
89 |
#' @param lbl_vars Named (`list`) of analysis labels. |
|
90 |
#' @returns a `PreDataTableLayouts` object. |
|
91 |
#' @keywords internal |
|
92 |
#' |
|
93 |
aet01_lyt <- function(arm_var, |
|
94 |
lbl_overall, |
|
95 |
anl_vars, |
|
96 |
anl_lbls, |
|
97 |
lbl_vars) { |
|
98 | 8x |
lyt_base <- basic_table(show_colcounts = TRUE) %>% |
99 | 8x |
split_cols_by_with_overall(arm_var, lbl_overall) |
100 | ||
101 | 8x |
lyt_ae1 <- lyt_base %>% |
102 | 8x |
analyze_num_patients( |
103 | 8x |
vars = "USUBJID", |
104 | 8x |
.stats = c("unique", "nonunique"), |
105 | 8x |
.labels = c( |
106 | 8x |
unique = render_safe("Total number of {patient_label} with at least one AE"), |
107 | 8x |
nonunique = "Total number of AEs" |
108 |
), |
|
109 | 8x |
.formats = list(unique = format_count_fraction_fixed_dp, nonunique = "xx"), |
110 | 8x |
show_labels = "hidden" |
111 |
) |
|
112 | ||
113 | 8x |
lyt_adsl <- lyt_base %>% |
114 | 8x |
count_patients_with_event( |
115 | 8x |
"USUBJID", |
116 | 8x |
filters = c("DTHFL" = "Y"), |
117 | 8x |
denom = "N_col", |
118 | 8x |
.labels = c(count_fraction = "Total number of deaths"), |
119 | 8x |
table_names = "TotDeath" |
120 |
) %>% |
|
121 | 8x |
count_patients_with_event( |
122 | 8x |
"USUBJID", |
123 | 8x |
filters = c("DCSREAS" = "ADVERSE EVENT"), |
124 | 8x |
denom = "N_col", |
125 | 8x |
.labels = c(count_fraction = render_safe("Total number of {patient_label} withdrawn from study due to an AE")), |
126 | 8x |
table_names = "TotWithdrawal" |
127 |
) |
|
128 | ||
129 | 8x |
lyt_ae2 <- lyt_base %>% |
130 | 8x |
count_patients_recursive( |
131 | 8x |
anl_vars = anl_vars, |
132 | 8x |
anl_lbls = anl_lbls, |
133 | 8x |
lbl_vars = lbl_vars |
134 |
) |
|
135 | ||
136 | 8x |
return(list(ae1 = lyt_ae1, ae2 = lyt_ae2, adsl = lyt_adsl)) |
137 |
} |
|
138 | ||
139 |
#' @describeIn aet01 Preprocessing |
|
140 |
#' |
|
141 |
#' @inheritParams aet01_main |
|
142 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
143 |
#' |
|
144 |
#' @export |
|
145 |
#' |
|
146 |
aet01_pre <- function(adam_db, ...) { |
|
147 | 1x |
adam_db$adae <- adam_db$adae %>% |
148 | 1x |
filter(.data$ANL01FL == "Y") %>% |
149 | 1x |
mutate( |
150 | 1x |
FATAL = with_label(.data$AESDTH == "Y", "AE with fatal outcome"), |
151 | 1x |
SER = with_label(.data$AESER == "Y", "Serious AE"), |
152 | 1x |
SEV = with_label(.data$ASEV == "SEVERE", "Severe AE (at greatest intensity)"), |
153 | 1x |
REL = with_label(.data$AREL == "Y", "Related AE"), |
154 | 1x |
WD = with_label(.data$AEACN == "DRUG WITHDRAWN", "AE leading to withdrawal from treatment"), |
155 | 1x |
DSM = with_label( |
156 | 1x |
.data$AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"), |
157 | 1x |
"AE leading to dose modification/interruption" |
158 |
), |
|
159 | 1x |
SERWD = with_label(.data$SER & .data$WD, "Serious AE leading to withdrawal from treatment"), |
160 | 1x |
SERDSM = with_label(.data$SER & .data$DSM, "Serious AE leading to dose modification/interruption"), |
161 | 1x |
RELSER = with_label(.data$SER & .data$REL, "Related Serious AE"), |
162 | 1x |
RELWD = with_label(.data$REL & .data$WD, "Related AE leading to withdrawal from treatment"), |
163 | 1x |
RELDSM = with_label(.data$REL & .data$DSM, "Related AE leading to dose modification/interruption"), |
164 | 1x |
CTC35 = with_label(.data$ATOXGR %in% c("3", "4", "5"), "Grade 3-5 AE"), |
165 | 1x |
CTC45 = with_label(.data$ATOXGR %in% c("4", "5"), "Grade 4/5 AE") |
166 |
) |
|
167 | ||
168 | 1x |
adam_db$adsl <- adam_db$adsl %>% |
169 | 1x |
mutate(DCSREAS = reformat(.data$DCSREAS, missing_rule)) |
170 | ||
171 | 1x |
adam_db |
172 |
} |
|
173 | ||
174 |
#' @describeIn aet01 Postprocessing |
|
175 |
#' |
|
176 |
#' @inheritParams gen_args |
|
177 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
178 |
#' |
|
179 |
#' @export |
|
180 |
#' |
|
181 |
aet01_post <- function(tlg, prune_0 = FALSE, ...) { |
|
182 | 1x |
if (prune_0) { |
183 | ! |
tlg <- smart_prune(tlg) |
184 |
} |
|
185 | 1x |
std_postprocessing(tlg) |
186 |
} |
|
187 | ||
188 |
#' `AET01` Table 1 (Default) Overview of Deaths and Adverse Events Summary Table 1. |
|
189 |
#' |
|
190 |
#' @include chevron_tlg-S4class.R |
|
191 |
#' @export |
|
192 |
#' |
|
193 |
#' @examples |
|
194 |
#' run(aet01, syn_data, arm_var = "ARM") |
|
195 |
aet01 <- chevron_t( |
|
196 |
main = aet01_main, |
|
197 |
preprocess = aet01_pre, |
|
198 |
postprocess = aet01_post |
|
199 |
) |
1 |
# aet01_aesi ---- |
|
2 | ||
3 |
#' @describeIn aet01_aesi Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param aesi_vars (`character`) the `AESI` variables to be included in the summary. Defaults to `NA`. |
|
7 |
#' @param grade_groups (`list`) the grade groups to be displayed. |
|
8 |
#' @returns the main function returns an `rtables` object. |
|
9 |
#' @details |
|
10 |
#' * Does not remove rows with zero counts by default. |
|
11 |
#' |
|
12 |
#' @note |
|
13 |
#' * `adam_db` object must contain an `adae` table with columns `"AEOUT"`, `"AEACN"`, `"AECONTRT"`, `"AESER"`, |
|
14 |
#' `"AREL"`, and the column specified by `arm_var`. |
|
15 |
#' * `aesi_vars` may contain any/all of the following variables to display: `"ALLRESWD"`, `"ALLRESDSM"`, |
|
16 |
#' `"ALLRESCONTRT"`, `"NOTRESWD"`, `"NOTRESDSM"`, `"NOTRESCONTRT"`, `"SERWD"`, `"SERDSM"`, `"SERCONTRT"`, |
|
17 |
#' `"RELWD"`, `"RELDSM"`, `"RELCONTRT"`, `"RELSER"`. |
|
18 |
#' * `aesi_vars` variable prefixes are defined as follows: |
|
19 |
#' * `"ALLRES"` = "all non-fatal adverse events resolved" |
|
20 |
#' * `"NOTRES"` = "at least one unresolved or ongoing non-fatal adverse event" |
|
21 |
#' * `"SER"` = "serious adverse event" |
|
22 |
#' * `"REL"` = "related adverse event" |
|
23 |
#' * `aesi_vars` variable suffixes are defined as follows: |
|
24 |
#' * `"WD"` = "patients with study drug withdrawn" |
|
25 |
#' * `"DSM"` = "patients with dose modified/interrupted" |
|
26 |
#' * `"CONTRT"` = "patients with treatment received" |
|
27 |
#' * Several `aesi_vars` can be added to the table at once: |
|
28 |
#' * `aesi_vars = "ALL"` will include all possible `aesi_vars`. |
|
29 |
#' * Including `"ALL_XXX"` in `aesi_vars` where `XXX` is one of the prefixes listed above will include all |
|
30 |
#' `aesi_vars` with that prefix. |
|
31 |
#' |
|
32 |
#' @export |
|
33 |
#' |
|
34 |
aet01_aesi_main <- function(adam_db, |
|
35 |
arm_var = "ACTARM", |
|
36 |
lbl_overall = NULL, |
|
37 |
aesi_vars = NULL, |
|
38 |
grade_groups = NULL, |
|
39 |
...) { |
|
40 | 1x |
assert_all_tablenames(adam_db, "adsl", "adae") |
41 | 1x |
assert_string(arm_var) |
42 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
43 | 1x |
assert_character(aesi_vars, null.ok = TRUE) |
44 | 1x |
assert_list(grade_groups, null.ok = TRUE) |
45 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var)) |
46 | 1x |
assert_valid_variable(adam_db$adae, c(arm_var)) |
47 | 1x |
assert_valid_variable(adam_db$adae, "USUBJID", empty_ok = TRUE) |
48 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adae, arm_var) |
49 | ||
50 | 1x |
if (is.null(grade_groups)) { |
51 | 1x |
grade_groups <- list( |
52 | 1x |
"Grade 1" = "1", |
53 | 1x |
"Grade 2" = "2", |
54 | 1x |
"Grade 3" = "3", |
55 | 1x |
"Grade 4" = "4", |
56 | 1x |
"Grade 5 (fatal outcome)" = "5" |
57 |
) |
|
58 |
} |
|
59 | 1x |
all_aesi_vars <- get_aesi_vars(aesi_vars) |
60 | 1x |
assert_valid_variable(adam_db$adae, c(all_aesi_vars), empty_ok = TRUE, na_ok = TRUE, types = list("logical")) |
61 | ||
62 | 1x |
lbl_overall <- render_safe(lbl_overall) |
63 | 1x |
lbl_aesi_vars <- var_labels_for(adam_db$adae, all_aesi_vars) |
64 | ||
65 | 1x |
lyt <- aet01_aesi_lyt( |
66 | 1x |
arm_var = arm_var, |
67 | 1x |
aesi_vars = all_aesi_vars, |
68 | 1x |
lbl_overall = lbl_overall, |
69 | 1x |
lbl_aesi_vars = lbl_aesi_vars, |
70 | 1x |
grade_groups = grade_groups |
71 |
) |
|
72 | ||
73 | 1x |
tbl <- build_table(lyt, adam_db$adae, alt_counts_df = adam_db$adsl) |
74 | ||
75 | 1x |
tbl |
76 |
} |
|
77 | ||
78 |
#' `aet01_aesi` Layout |
|
79 |
#' |
|
80 |
#' @inheritParams gen_args |
|
81 |
#' @param lbl_aesi_vars (`character`) the labels of the `AESI` variables to be summarized. |
|
82 |
#' @returns a `PreDataTableLayouts` object. |
|
83 |
#' @keywords internal |
|
84 |
#' |
|
85 |
aet01_aesi_lyt <- function(arm_var, |
|
86 |
aesi_vars, |
|
87 |
lbl_overall, |
|
88 |
lbl_aesi_vars, |
|
89 |
grade_groups) { |
|
90 | 6x |
names(lbl_aesi_vars) <- aesi_vars |
91 | 6x |
basic_table(show_colcounts = TRUE) %>% |
92 | 6x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
93 | 6x |
count_patients_with_event( |
94 | 6x |
vars = "USUBJID", |
95 | 6x |
filters = c("ANL01FL" = "Y"), |
96 | 6x |
denom = "N_col", |
97 | 6x |
.labels = c(count_fraction = render_safe("Total number of {patient_label} with at least one AE")) |
98 |
) %>% |
|
99 | 6x |
count_values( |
100 | 6x |
"ANL01FL", |
101 | 6x |
values = "Y", |
102 | 6x |
.stats = "count", |
103 | 6x |
.labels = c(count = "Total number of AEs"), |
104 | 6x |
table_names = "total_aes" |
105 |
) %>% |
|
106 | 6x |
count_occurrences_by_grade( |
107 | 6x |
var = "ATOXGR", |
108 | 6x |
var_labels = render_safe("Total number of {patient_label} with at least one AE by worst grade"), |
109 | 6x |
show_labels = "visible", |
110 | 6x |
grade_groups = grade_groups |
111 |
) %>% |
|
112 | 6x |
count_patients_with_flags( |
113 | 6x |
"USUBJID", |
114 | 6x |
flag_variables = lbl_aesi_vars, |
115 | 6x |
denom = "N_col" |
116 |
) |
|
117 |
} |
|
118 | ||
119 |
#' @describeIn aet01_aesi Preprocessing |
|
120 |
#' |
|
121 |
#' @inheritParams aet01_aesi_main |
|
122 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
123 |
#' |
|
124 |
#' @export |
|
125 |
#' |
|
126 |
aet01_aesi_pre <- function(adam_db, |
|
127 |
...) { |
|
128 | 1x |
adam_db$adae <- adam_db$adae %>% |
129 | 1x |
filter(.data$ANL01FL == "Y") %>% |
130 | 1x |
mutate( |
131 | 1x |
NOT_RESOLVED = with_label( |
132 | 1x |
.data$AEOUT %in% c("NOT RECOVERED/NOT RESOLVED", "RECOVERING/RESOLVING", "UNKNOWN"), |
133 | 1x |
"Total number of {patient_label} with at least one unresolved or ongoing non-fatal AE" |
134 |
), |
|
135 | 1x |
ALL_RESOLVED = with_label( |
136 | 1x |
!.data$AEOUT %in% "FATAL" & !.data$NOT_RESOLVED, |
137 | 1x |
"Total number of {patient_label} with all non-fatal AEs resolved" |
138 |
), |
|
139 | 1x |
WD = with_label( |
140 | 1x |
.data$AEACN %in% "DRUG WITHDRAWN", "Total number of {patient_label} with study drug withdrawn due to AE" |
141 |
), |
|
142 | 1x |
DSM = with_label( |
143 | 1x |
.data$AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"), |
144 | 1x |
"Total number of {patient_label} with dose modified/interrupted due to AE" |
145 |
), |
|
146 | 1x |
CONTRT = with_label( |
147 | 1x |
.data$AECONTRT %in% "Y", "Total number of {patient_label} with treatment received for AE" |
148 |
), |
|
149 | 1x |
SER = with_label( |
150 | 1x |
.data$AESER %in% "Y", "Total number of {patient_label} with at least one serious AE" |
151 |
), |
|
152 | 1x |
REL = with_label( |
153 | 1x |
.data$AREL %in% "Y", "Total number of {patient_label} with at least one related AE" |
154 |
), |
|
155 | 1x |
ALLRESWD = with_label( |
156 | 1x |
.data$WD & .data$ALL_RESOLVED, " No. of {patient_label} with study drug withdrawn due to resolved AE" |
157 |
), |
|
158 | 1x |
ALLRESDSM = with_label( |
159 | 1x |
.data$DSM & .data$ALL_RESOLVED, " No. of {patient_label} with dose modified/interrupted due to resolved AE" |
160 |
), |
|
161 | 1x |
ALLRESCONTRT = with_label( |
162 | 1x |
.data$CONTRT & .data$ALL_RESOLVED, " No. of {patient_label} with treatment received for resolved AE" |
163 |
), |
|
164 | 1x |
NOTRESWD = with_label( |
165 | 1x |
.data$WD & .data$NOT_RESOLVED, |
166 | 1x |
" No. of {patient_label} with study drug withdrawn due to unresolved or ongoing AE" |
167 |
), |
|
168 | 1x |
NOTRESDSM = with_label( |
169 | 1x |
.data$DSM & .data$NOT_RESOLVED, |
170 | 1x |
" No. of {patient_label} with dose modified/interrupted due to unresolved or ongoing AE" |
171 |
), |
|
172 | 1x |
NOTRESCONTRT = with_label( |
173 | 1x |
.data$CONTRT & .data$NOT_RESOLVED, |
174 | 1x |
" No. of {patient_label} with treatment received for unresolved/ongoing AE" |
175 |
), |
|
176 | 1x |
SERWD = with_label( |
177 | 1x |
.data$SER & .data$WD, " No. of {patient_label} with study drug withdrawn due to serious AE" |
178 |
), |
|
179 | 1x |
SERDSM = with_label( |
180 | 1x |
.data$SER & .data$DSM, " No. of {patient_label} with dose modified/interrupted due to serious AE" |
181 |
), |
|
182 | 1x |
SERCONTRT = with_label( |
183 | 1x |
.data$SER & .data$CONTRT, " No. of {patient_label} with treatment received for serious AE" |
184 |
), |
|
185 | 1x |
RELWD = with_label( |
186 | 1x |
.data$REL & .data$WD, " No. of {patient_label} with study drug withdrawn due to related AE" |
187 |
), |
|
188 | 1x |
RELDSM = with_label( |
189 | 1x |
.data$REL & .data$DSM, " No. of {patient_label} with dose modified/interrupted due to related AE" |
190 |
), |
|
191 | 1x |
RELCONTRT = with_label( |
192 | 1x |
.data$REL & .data$CONTRT, " No. of {patient_label} with treatment received for related AE" |
193 |
), |
|
194 | 1x |
RELSER = with_label( |
195 | 1x |
.data$REL & .data$SER, " No. of {patient_label} with serious, related AE" |
196 |
) |
|
197 |
) %>% |
|
198 | 1x |
mutate( |
199 | 1x |
ATOXGR = factor(.data$ATOXGR, levels = 1:5) |
200 |
) |
|
201 | ||
202 | 1x |
adam_db |
203 |
} |
|
204 | ||
205 |
#' @describeIn aet01_aesi Postprocessing |
|
206 |
#' |
|
207 |
#' @inheritParams gen_args |
|
208 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
209 |
#' |
|
210 |
#' @export |
|
211 |
#' |
|
212 |
aet01_aesi_post <- function(tlg, prune_0 = FALSE, ...) { |
|
213 | 1x |
if (prune_0) { |
214 | ! |
tlg <- smart_prune(tlg) |
215 |
} |
|
216 | 1x |
std_postprocessing(tlg) |
217 |
} |
|
218 | ||
219 |
#' `AET01_AESI` Table 1 (Default) Adverse Event of Special Interest Summary Table. |
|
220 |
#' |
|
221 |
#' @include chevron_tlg-S4class.R |
|
222 |
#' @export |
|
223 |
#' |
|
224 |
#' @examples |
|
225 |
#' run(aet01_aesi, syn_data) |
|
226 |
aet01_aesi <- chevron_t( |
|
227 |
main = aet01_aesi_main, |
|
228 |
preprocess = aet01_aesi_pre, |
|
229 |
postprocess = aet01_aesi_post |
|
230 |
) |
|
231 | ||
232 |
#' @keywords internal |
|
233 |
get_aesi_vars <- function(aesi_vars) { |
|
234 | 1x |
if ("ALL" %in% aesi_vars) aesi_vars <- c("ALL_ALLRES", "ALL_NOTRES", "ALL_SER", "ALL_REL") |
235 | 6x |
if (any(grepl("^ALL_", aesi_vars))) { |
236 | 1x |
aesi <- c(grep("^ALL_", aesi_vars, value = TRUE, invert = TRUE), sapply( |
237 | 1x |
c("WD", "DSM", "CONTRT"), |
238 | 1x |
function(x) sub("^(ALL_)(.*)", paste0("\\2", x), grep("^ALL_", aesi_vars, value = TRUE)) |
239 |
)) |
|
240 | 1x |
if ("ALL_REL" %in% aesi_vars) aesi <- c(aesi, "RELSER") |
241 |
} else { |
|
242 | 5x |
aesi <- aesi_vars |
243 |
} |
|
244 | 6x |
all_aesi_vars <- c( |
245 | 6x |
"WD", "DSM", "CONTRT", "ALL_RESOLVED", grep("^ALLRES", aesi, value = TRUE), |
246 | 6x |
"NOT_RESOLVED", grep("^NOTRES", aesi, value = TRUE), "SER", grep("^SER", aesi, value = TRUE), |
247 | 6x |
"REL", grep("^REL", aesi, value = TRUE) |
248 |
) |
|
249 | 6x |
return(all_aesi_vars) |
250 |
} |
1 |
# pdt01 ---- |
|
2 | ||
3 |
#' @describeIn pdt01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param dvcode_var (`string`) the variable defining the protocol deviation coded term. By default `DVDECOD`. |
|
7 |
#' @param dvterm_var (`string`) the variable defining the protocol deviation term. By default `DVTERM`. |
|
8 |
#' @returns the main function returns an `rtables` object. |
|
9 |
#' |
|
10 |
#' @details |
|
11 |
#' * Data should be filtered for major protocol deviations. `(DVCAT == "MAJOR")`. |
|
12 |
#' * Numbers represent absolute numbers of subjects and fraction of `N`, or absolute numbers when specified. |
|
13 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
14 |
#' * Split columns by arm. |
|
15 |
#' * Does not include a total column by default. |
|
16 |
#' * Sort by medication class alphabetically and within medication class by decreasing total number of patients with |
|
17 |
#' the specific medication. |
|
18 |
#' |
|
19 |
#' @note |
|
20 |
#' * `adam_db` object must contain an `addv` table with the columns specified in `dvcode_var` and `dvterm_var` as well |
|
21 |
#' as `"DVSEQ"`. |
|
22 |
#' |
|
23 |
#' @export |
|
24 |
#' |
|
25 |
pdt01_main <- function(adam_db, |
|
26 |
arm_var = "ARM", |
|
27 |
lbl_overall = NULL, |
|
28 |
dvcode_var = "DVDECOD", |
|
29 |
dvterm_var = "DVTERM", |
|
30 |
...) { |
|
31 | 1x |
assert_all_tablenames(adam_db, c("adsl", "addv")) |
32 | 1x |
assert_string(arm_var) |
33 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
34 | 1x |
assert_string(dvcode_var) |
35 | 1x |
assert_string(dvterm_var) |
36 | 1x |
assert_valid_variable(adam_db$addv, c(dvcode_var, dvterm_var), types = list(c("character", "factor"))) |
37 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
38 | 1x |
assert_valid_variable(adam_db$addv, "USUBJID", types = list(c("character", "factor")), empty_ok = TRUE) |
39 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$addv, arm_var) |
40 | ||
41 | 1x |
lbl_overall <- render_safe(lbl_overall) |
42 | 1x |
lbl_dvcode_var <- var_labels_for(adam_db$addv, dvcode_var) |
43 | 1x |
lbl_dvterm_var <- var_labels_for(adam_db$addv, dvterm_var) |
44 | ||
45 | 1x |
lyt <- pdt01_lyt( |
46 | 1x |
arm_var = arm_var, |
47 | 1x |
lbl_overall = lbl_overall, |
48 | 1x |
dvcode_var = dvcode_var, |
49 | 1x |
lbl_dvcode_var = lbl_dvcode_var, |
50 | 1x |
dvterm_var = dvterm_var, |
51 | 1x |
lbl_dvterm_var = lbl_dvterm_var |
52 |
) |
|
53 | ||
54 | 1x |
tbl <- build_table(lyt, adam_db$addv, alt_counts_df = adam_db$adsl) |
55 | ||
56 | 1x |
tbl |
57 |
} |
|
58 | ||
59 |
#' `pdt01` Layout |
|
60 |
#' |
|
61 |
#' @inheritParams gen_args |
|
62 |
#' @inheritParams pdt01_main |
|
63 |
#' @param lbl_dvcode_var (`string`) label for the variable defining the protocol deviation coded term. |
|
64 |
#' @param lbl_dvterm_var (`string`) label for the variable defining the protocol deviation term. |
|
65 |
#' |
|
66 |
#' @keywords internal |
|
67 |
#' |
|
68 |
pdt01_lyt <- function(arm_var, |
|
69 |
lbl_overall, |
|
70 |
dvcode_var, |
|
71 |
lbl_dvcode_var, |
|
72 |
dvterm_var, |
|
73 |
lbl_dvterm_var) { |
|
74 | 4x |
basic_table(show_colcounts = TRUE) %>% |
75 | 4x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
76 | 4x |
summarize_num_patients( |
77 | 4x |
var = "USUBJID", |
78 | 4x |
.stats = c("unique", "nonunique"), |
79 | 4x |
.labels = c( |
80 | 4x |
unique = render_safe("Total number of {patient_label} with at least one major protocol deviation"), |
81 | 4x |
nonunique = "Total number of major protocol deviations" |
82 |
), |
|
83 | 4x |
.formats = list(unique = format_count_fraction_fixed_dp) |
84 |
) %>% |
|
85 | 4x |
split_rows_by( |
86 | 4x |
dvcode_var, |
87 | 4x |
child_labels = "visible", |
88 | 4x |
nested = FALSE, |
89 | 4x |
indent_mod = -1L, |
90 | 4x |
split_fun = drop_split_levels, |
91 | 4x |
label_pos = "topleft", |
92 | 4x |
split_label = lbl_dvterm_var |
93 |
) %>% |
|
94 | 4x |
count_occurrences(vars = dvterm_var) %>% |
95 | 4x |
append_topleft(paste0(" Description")) |
96 |
} |
|
97 | ||
98 |
#' @describeIn pdt01 Preprocessing |
|
99 |
#' |
|
100 |
#' @inheritParams pdt01_main |
|
101 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
102 |
#' @export |
|
103 |
#' |
|
104 |
pdt01_pre <- function(adam_db, ...) { |
|
105 | 1x |
adam_db$addv <- adam_db$addv %>% |
106 | 1x |
mutate(across(all_of(c("DVDECOD", "DVTERM")), ~ reformat(.x, nocoding))) %>% |
107 | 1x |
mutate( |
108 | 1x |
DVDECOD = with_label(.data$DVDECOD, "Protocol Deviation Coded Term"), |
109 | 1x |
DVTERM = with_label(.data$DVTERM, "Category") |
110 |
) |
|
111 | ||
112 | 1x |
adam_db %>% |
113 | 1x |
dunlin::log_filter(.data$DVCAT == "MAJOR", "addv") |
114 |
} |
|
115 | ||
116 |
#' @describeIn pdt01 Postprocessing |
|
117 |
#' |
|
118 |
#' @inheritParams pdt01_main |
|
119 |
#' @inheritParams gen_args |
|
120 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
121 |
#' @export |
|
122 |
#' |
|
123 |
pdt01_post <- function(tlg, prune_0 = TRUE, dvcode_var = "DVDECOD", dvterm_var = "DVTERM", ...) { |
|
124 | 1x |
if (prune_0) { |
125 | 1x |
tlg <- smart_prune(tlg) |
126 |
} |
|
127 | ||
128 | 1x |
tbl_sorted <- tlg %>% |
129 | 1x |
sort_at_path( |
130 | 1x |
path = c(dvcode_var, "*", dvterm_var), |
131 | 1x |
scorefun = score_occurrences |
132 |
) |
|
133 | ||
134 | 1x |
std_postprocessing(tbl_sorted) |
135 |
} |
|
136 | ||
137 |
#' `pdt01` Major Protocol Deviations Table. |
|
138 |
#' |
|
139 |
#' A major protocol deviations |
|
140 |
#' table with the number of subjects and the total number of treatments by medication class sorted alphabetically and |
|
141 |
#' medication name sorted by frequencies. |
|
142 |
#' |
|
143 |
#' @include chevron_tlg-S4class.R |
|
144 |
#' @export |
|
145 |
#' |
|
146 |
#' @examples |
|
147 |
#' run(pdt01, syn_data) |
|
148 |
pdt01 <- chevron_t( |
|
149 |
main = pdt01_main, |
|
150 |
preprocess = pdt01_pre, |
|
151 |
postprocess = pdt01_post |
|
152 |
) |
1 |
# cfbt01 ---- |
|
2 | ||
3 |
#' @describeIn cfbt01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param summaryvars (`character`) variables to be analyzed. The label attribute of the corresponding column in |
|
7 |
#' table of `adam_db` is used as label. |
|
8 |
#' @param visitvar (`string`) typically one of `"AVISIT"` or user-defined visit incorporating `"ATPT"`. |
|
9 |
#' @param precision (named `list` of `integer`) where names are values found in the `PARAMCD` column and the values |
|
10 |
#' indicate the number of digits in statistics. If `default` is set, and parameter precision not specified, |
|
11 |
#' the value for `default` will be used. |
|
12 |
#' @param .stats (`character`) statistics names, see `tern::analyze_vars()`. |
|
13 |
#' @param skip Named (`list`) of visit values that need to be inhibited. |
|
14 |
#' @param ... additional arguments like `.indent_mods`, `.labels`. |
|
15 |
#' @returns the main function returns an `rtables` object. |
|
16 |
#' |
|
17 |
#' @details |
|
18 |
#' * The `Analysis Value` column, displays the number of patients, the mean, standard deviation, median and range of |
|
19 |
#' the analysis value for each visit. |
|
20 |
#' * The `Change from Baseline` column, displays the number of patient and the mean, standard deviation, |
|
21 |
#' median and range of changes relative to the baseline. |
|
22 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
23 |
#' * Split columns by arm, typically `ACTARM`. |
|
24 |
#' * Does not include a total column by default. |
|
25 |
#' * Sorted based on factor level; first by `PARAM` labels in alphabetic order then by chronological time point given |
|
26 |
#' by `AVISIT`. Re-level to customize order |
|
27 |
#' |
|
28 |
#' @note |
|
29 |
#' * `adam_db` object must contain table named as `dataset` with the columns specified in `summaryvars`. |
|
30 |
#' |
|
31 |
#' @export |
|
32 |
#' |
|
33 |
cfbt01_main <- function(adam_db, |
|
34 |
dataset, |
|
35 |
arm_var = "ACTARM", |
|
36 |
lbl_overall = NULL, |
|
37 |
row_split_var = NULL, |
|
38 |
summaryvars = c("AVAL", "CHG"), |
|
39 |
visitvar = "AVISIT", |
|
40 |
precision = list(default = 2L), |
|
41 |
page_var = "PARAMCD", |
|
42 |
.stats = c("n", "mean_sd", "median", "range"), |
|
43 |
skip = list(CHG = "BASELINE"), |
|
44 |
...) { |
|
45 | 5x |
assert_all_tablenames(adam_db, c("adsl", dataset)) |
46 | 5x |
assert_string(arm_var) |
47 | 5x |
assert_string(lbl_overall, null.ok = TRUE) |
48 | 5x |
assert_character(summaryvars, max.len = 2L, min.len = 1L) |
49 | 5x |
assert_character(row_split_var, null.ok = TRUE) |
50 | 5x |
assert_disjunct(row_split_var, c("PARAMCD", "PARAM", visitvar)) |
51 | 5x |
assert_string(visitvar) |
52 | 5x |
assert_string(page_var, null.ok = TRUE) |
53 | 5x |
assert_subset(page_var, c(row_split_var, "PARAMCD")) |
54 | 5x |
df_lbl <- paste0("adam_db$", dataset) |
55 | 5x |
assert_valid_variable(adam_db[[dataset]], c(summaryvars), types = list("numeric"), empty_ok = TRUE, label = df_lbl) |
56 | 5x |
assert_valid_variable( |
57 | 5x |
adam_db[[dataset]], c(visitvar, row_split_var, "PARAM", "PARAMCD"), |
58 | 5x |
types = list(c("character", "factor")), label = df_lbl |
59 |
) |
|
60 | 5x |
assert_valid_variable( |
61 | 5x |
adam_db[[dataset]], "USUBJID", |
62 | 5x |
types = list(c("character", "factor")), empty_ok = TRUE, label = df_lbl |
63 |
) |
|
64 | 5x |
assert_valid_variable(adam_db$adsl, "USUBJID", types = list(c("character", "factor"))) |
65 | 5x |
assert_valid_var_pair(adam_db$adsl, adam_db[[dataset]], arm_var) |
66 | 5x |
assert_list(precision, types = "integerish", names = "unique") |
67 | ||
68 | 5x |
vapply(precision, assert_int, FUN.VALUE = numeric(1), lower = 0) |
69 | 5x |
all_stats <- c( |
70 | 5x |
"n", "sum", "mean", "sd", "se", "mean_sd", "mean_se", "mean_ci", "mean_sei", |
71 | 5x |
"mean_sdi", "mean_pval", "median", "mad", "median_ci", "quantiles", "iqr", "range", |
72 | 5x |
"cv", "min", "max", "median_range", "geom_mean", "geom_cv" |
73 |
) |
|
74 | 5x |
assert_subset(.stats, all_stats) |
75 | ||
76 | 5x |
lbl_overall <- render_safe(lbl_overall) |
77 | 5x |
lbl_avisit <- var_labels_for(adam_db[[dataset]], visitvar) |
78 | 5x |
lbl_param <- var_labels_for(adam_db[[dataset]], "PARAM") |
79 | ||
80 | 5x |
summaryvars_lbls <- var_labels_for(adam_db[[dataset]], summaryvars) |
81 | 5x |
row_split_lbl <- var_labels_for(adam_db[[dataset]], row_split_var) |
82 | ||
83 | 5x |
lyt <- cfbt01_lyt( |
84 | 5x |
arm_var = arm_var, |
85 | 5x |
lbl_overall = lbl_overall, |
86 | 5x |
lbl_avisit = lbl_avisit, |
87 | 5x |
lbl_param = lbl_param, |
88 | 5x |
summaryvars = summaryvars, |
89 | 5x |
summaryvars_lbls = summaryvars_lbls, |
90 | 5x |
row_split_var = row_split_var, |
91 | 5x |
row_split_lbl = row_split_lbl, |
92 | 5x |
visitvar = visitvar, |
93 | 5x |
precision = precision, |
94 | 5x |
.stats = .stats, |
95 | 5x |
page_var = page_var, |
96 | 5x |
skip = skip, |
97 |
... |
|
98 |
) |
|
99 | ||
100 | 5x |
tbl <- build_table( |
101 | 5x |
lyt, |
102 | 5x |
df = adam_db[[dataset]], |
103 | 5x |
alt_counts_df = adam_db$adsl |
104 |
) |
|
105 | ||
106 | 5x |
tbl |
107 |
} |
|
108 | ||
109 |
#' `cfbt01` Layout |
|
110 |
#' |
|
111 |
#' @inheritParams gen_args |
|
112 |
#' @inheritParams cfbt01_main |
|
113 |
#' |
|
114 |
#' @param lbl_avisit (`string`) label of the `visitvar` variable. |
|
115 |
#' @param lbl_param (`string`) label of the `PARAM` variable. |
|
116 |
#' @param summaryvars (`character`) the variables to be analyzed. For this table, `AVAL` and `CHG` by default. |
|
117 |
#' @param summaryvars_lbls (`character`) the label of the variables to be analyzed. |
|
118 |
#' @param row_split_lbl (`character`) label of further row splits. |
|
119 |
#' @param visitvar (`string`) typically one of `"AVISIT"` or user-defined visit incorporating `"ATPT"`. |
|
120 |
#' @returns a `PreDataTableLayouts` object. |
|
121 |
#' |
|
122 |
#' @keywords internal |
|
123 |
#' |
|
124 |
cfbt01_lyt <- function(arm_var, |
|
125 |
lbl_overall, |
|
126 |
lbl_avisit, |
|
127 |
lbl_param, |
|
128 |
summaryvars, |
|
129 |
summaryvars_lbls, |
|
130 |
row_split_var, |
|
131 |
row_split_lbl, |
|
132 |
visitvar, |
|
133 |
precision, |
|
134 |
page_var, |
|
135 |
.stats, |
|
136 |
skip, |
|
137 |
...) { |
|
138 | 12x |
page_by <- get_page_by(page_var, c(row_split_var, "PARAMCD")) |
139 | 12x |
label_pos <- ifelse(page_by, "hidden", "topleft") |
140 | 12x |
basic_table(show_colcounts = TRUE) %>% |
141 | 12x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
142 | 12x |
split_rows_by_recursive( |
143 | 12x |
row_split_var, |
144 | 12x |
split_label = row_split_lbl, |
145 | 12x |
label_pos = head(label_pos, -1L), page_by = head(page_by, -1L) |
146 |
) %>% |
|
147 | 12x |
split_rows_by( |
148 | 12x |
var = "PARAMCD", |
149 | 12x |
labels_var = "PARAM", |
150 | 12x |
split_fun = drop_split_levels, |
151 | 12x |
label_pos = tail(label_pos, 1L), |
152 | 12x |
split_label = lbl_param, |
153 | 12x |
page_by = tail(page_by, 1L) |
154 |
) %>% |
|
155 | 12x |
split_rows_by( |
156 | 12x |
visitvar, |
157 | 12x |
split_fun = drop_split_levels, |
158 | 12x |
label_pos = "topleft", |
159 | 12x |
split_label = lbl_avisit |
160 |
) %>% |
|
161 | 12x |
split_cols_by_multivar( |
162 | 12x |
vars = summaryvars, |
163 | 12x |
varlabels = summaryvars_lbls, |
164 | 12x |
nested = TRUE |
165 |
) %>% |
|
166 | 12x |
analyze_colvars( |
167 | 12x |
afun = afun_skip, |
168 | 12x |
extra_args = list( |
169 | 12x |
visitvar = visitvar, |
170 | 12x |
paramcdvar = "PARAMCD", |
171 | 12x |
skip = skip, |
172 | 12x |
precision = precision, |
173 | 12x |
.stats = .stats, |
174 |
... |
|
175 |
) |
|
176 |
) |
|
177 |
} |
|
178 | ||
179 |
#' @describeIn cfbt01 Preprocessing |
|
180 |
#' |
|
181 |
#' @inheritParams gen_args |
|
182 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
183 |
#' @export |
|
184 |
#' |
|
185 |
cfbt01_pre <- function(adam_db, dataset, ...) { |
|
186 | 5x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
187 | 5x |
filter(.data$ANL01FL == "Y") %>% |
188 | 5x |
mutate( |
189 | 5x |
AVISIT = reorder(.data$AVISIT, .data$AVISITN), |
190 | 5x |
AVISIT = with_label(.data$AVISIT, "Analysis Visit"), |
191 | 5x |
AVAL = with_label(.data$AVAL, "Value at Visit"), |
192 | 5x |
CHG = with_label(.data$CHG, "Change from \nBaseline") |
193 |
) |
|
194 | ||
195 | 5x |
adam_db |
196 |
} |
|
197 | ||
198 |
#' @describeIn cfbt01 Postprocessing |
|
199 |
#' |
|
200 |
#' @inheritParams gen_args |
|
201 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
202 |
#' @export |
|
203 |
cfbt01_post <- function(tlg, prune_0 = TRUE, ...) { |
|
204 | 5x |
if (prune_0) { |
205 | 5x |
tlg <- smart_prune(tlg) |
206 |
} |
|
207 | 5x |
std_postprocessing(tlg) |
208 |
} |
|
209 | ||
210 |
#' `CFBT01` Change from Baseline By Visit Table. |
|
211 |
#' |
|
212 |
#' The `CFBT01` table provides an |
|
213 |
#' overview of the actual values and its change from baseline of each respective arm |
|
214 |
#' over the course of the trial. |
|
215 |
#' |
|
216 |
#' @include chevron_tlg-S4class.R |
|
217 |
#' @export |
|
218 |
#' |
|
219 |
#' @examples |
|
220 |
#' library(dunlin) |
|
221 |
#' |
|
222 |
#' proc_data <- log_filter( |
|
223 |
#' syn_data, |
|
224 |
#' PARAMCD %in% c("DIABP", "SYSBP"), "advs" |
|
225 |
#' ) |
|
226 |
#' run(cfbt01, proc_data, dataset = "advs") |
|
227 |
cfbt01 <- chevron_t( |
|
228 |
main = cfbt01_main, |
|
229 |
preprocess = cfbt01_pre, |
|
230 |
postprocess = cfbt01_post |
|
231 |
) |
1 |
# aet04 ---- |
|
2 | ||
3 |
#' @describeIn aet04 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param grade_groups (`list`) putting in correspondence toxicity grades and labels. |
|
7 |
#' @returns the main function returns an `rtables` object. |
|
8 |
#' |
|
9 |
#' @details |
|
10 |
#' * Numbers represent absolute numbers of patients and fraction of `N`, or absolute number of event when specified. |
|
11 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
12 |
#' * Events with missing grading values are excluded. |
|
13 |
#' * Split columns by arm, typically `ACTARM`. |
|
14 |
#' * Does not include a total column by default. |
|
15 |
#' * Sort Body System or Organ Class and Dictionary-Derived Term by highest overall frequencies. Analysis Toxicity |
|
16 |
#' Grade is sorted by severity. |
|
17 |
#' |
|
18 |
#' @note |
|
19 |
#' * `adam_db` object must contain an `adae` table with the columns `"AEBODSYS"`, `"AEDECOD"` and `"ATOXGR"`. |
|
20 |
#' |
|
21 |
#' @export |
|
22 |
#' |
|
23 |
aet04_main <- function(adam_db, |
|
24 |
arm_var = "ACTARM", |
|
25 |
lbl_overall = NULL, |
|
26 |
grade_groups = NULL, |
|
27 |
...) { |
|
28 | 1x |
assert_all_tablenames(adam_db, "adsl", "adae") |
29 | 1x |
assert_string(arm_var) |
30 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
31 | 1x |
assert_list(grade_groups, types = "character", null.ok = TRUE) |
32 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
33 | 1x |
assert_valid_variable(adam_db$adae, c(arm_var, "AEBODSYS", "AEDECOD"), types = list(c("character", "factor"))) |
34 | 1x |
assert_valid_variable(adam_db$adae, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
35 | 1x |
assert_valid_variable(adam_db$adae, "ATOXGR", na_ok = TRUE, types = list("factor")) |
36 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adae, arm_var) |
37 | ||
38 | 1x |
lbl_overall <- render_safe(lbl_overall) |
39 | 1x |
lbl_aebodsys <- var_labels_for(adam_db$adae, "AEBODSYS") |
40 | 1x |
lbl_aedecod <- var_labels_for(adam_db$adae, "AEDECOD") |
41 | ||
42 | 1x |
if (is.null(grade_groups)) { |
43 | 1x |
grade_groups <- list( |
44 | 1x |
"Grade 1-2" = c("1", "2"), |
45 | 1x |
"Grade 3-4" = c("3", "4"), |
46 | 1x |
"Grade 5" = c("5") |
47 |
) |
|
48 |
} |
|
49 | ||
50 | 1x |
lyt <- aet04_lyt( |
51 | 1x |
arm_var = arm_var, |
52 | 1x |
total_var = "TOTAL_VAR", |
53 | 1x |
lbl_overall = lbl_overall, |
54 | 1x |
lbl_aebodsys = lbl_aebodsys, |
55 | 1x |
lbl_aedecod = lbl_aedecod, |
56 | 1x |
grade_groups = grade_groups |
57 |
) |
|
58 | ||
59 | 1x |
adam_db$adae$TOTAL_VAR <- "- Any adverse events - " |
60 | ||
61 | 1x |
tbl <- build_table(lyt, df = adam_db$adae, alt_counts_df = adam_db$adsl) |
62 | ||
63 | 1x |
tbl |
64 |
} |
|
65 | ||
66 |
#' `aet04` Layout |
|
67 |
#' |
|
68 |
#' @inheritParams aet04_main |
|
69 |
#' |
|
70 |
#' @param total_var (`string`) variable to create summary of all variables. |
|
71 |
#' @param lbl_aebodsys (`string`) text label for `AEBODSYS`. |
|
72 |
#' @param lbl_aedecod (`string`) text label for `AEDECOD`. |
|
73 |
#' @param grade_groups (`list`) putting in correspondence toxicity grades and labels. |
|
74 |
#' @returns a `PreDataTableLayouts` object. |
|
75 |
#' @keywords internal |
|
76 |
#' |
|
77 |
aet04_lyt <- function(arm_var, |
|
78 |
total_var, |
|
79 |
lbl_overall, |
|
80 |
lbl_aebodsys, |
|
81 |
lbl_aedecod, |
|
82 |
grade_groups) { |
|
83 | 11x |
basic_table(show_colcounts = TRUE) %>% |
84 | 11x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
85 | 11x |
split_rows_by( |
86 | 11x |
var = total_var, |
87 | 11x |
label_pos = "hidden", |
88 | 11x |
child_labels = "visible", |
89 | 11x |
indent_mod = -1L |
90 |
) %>% |
|
91 | 11x |
summarize_num_patients( |
92 | 11x |
var = "USUBJID", |
93 | 11x |
.stats = "unique", |
94 | 11x |
.labels = "- Any Grade -", |
95 | 11x |
.indent_mods = 7L |
96 |
) %>% |
|
97 | 11x |
count_occurrences_by_grade( |
98 | 11x |
var = "ATOXGR", |
99 | 11x |
grade_groups = grade_groups, |
100 | 11x |
.indent_mods = 6L |
101 |
) %>% |
|
102 | 11x |
split_rows_by( |
103 | 11x |
"AEBODSYS", |
104 | 11x |
child_labels = "visible", |
105 | 11x |
nested = FALSE, |
106 | 11x |
split_fun = drop_split_levels, |
107 | 11x |
label_pos = "topleft", |
108 | 11x |
split_label = lbl_aebodsys |
109 |
) %>% |
|
110 | 11x |
split_rows_by( |
111 | 11x |
"AEDECOD", |
112 | 11x |
child_labels = "visible", |
113 | 11x |
split_fun = add_overall_level("- Overall -", trim = TRUE), |
114 | 11x |
label_pos = "topleft", |
115 | 11x |
split_label = lbl_aedecod |
116 |
) %>% |
|
117 | 11x |
summarize_num_patients( |
118 | 11x |
var = "USUBJID", |
119 | 11x |
.stats = "unique", |
120 | 11x |
.labels = "- Any Grade -", |
121 | 11x |
.indent_mods = 6L |
122 |
) %>% |
|
123 | 11x |
count_occurrences_by_grade( |
124 | 11x |
var = "ATOXGR", |
125 | 11x |
grade_groups = grade_groups, |
126 | 11x |
.indent_mods = 5L |
127 |
) %>% |
|
128 | 11x |
append_topleft(" Grade") |
129 |
} |
|
130 | ||
131 |
#' @describeIn aet04 Preprocessing |
|
132 |
#' |
|
133 |
#' @inheritParams gen_args |
|
134 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
135 |
#' @export |
|
136 |
#' |
|
137 |
aet04_pre <- function(adam_db, ...) { |
|
138 | 1x |
atoxgr_lvls <- c("1", "2", "3", "4", "5") |
139 | 1x |
adam_db$adae <- adam_db$adae %>% |
140 | 1x |
filter(.data$ANL01FL == "Y") %>% |
141 | 1x |
mutate( |
142 | 1x |
AEBODSYS = reformat(.data$AEBODSYS, nocoding), |
143 | 1x |
AEDECOD = reformat(.data$AEDECOD, nocoding), |
144 | 1x |
ATOXGR = factor(.data$ATOXGR, levels = atoxgr_lvls) |
145 |
) |
|
146 | 1x |
adam_db |
147 |
} |
|
148 | ||
149 |
#' @describeIn aet04 Postprocessing |
|
150 |
#' |
|
151 |
#' @inheritParams gen_args |
|
152 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
153 |
#' @export |
|
154 |
#' |
|
155 |
aet04_post <- function(tlg, prune_0 = TRUE, ...) { |
|
156 | 1x |
tlg <- tlg %>% |
157 | 1x |
tlg_sort_by_vars(c("AEBODSYS", "AEDECOD"), score_all_sum, decreasing = TRUE) |
158 | 1x |
if (prune_0) tlg <- trim_rows(tlg) |
159 | 1x |
std_postprocessing(tlg) |
160 |
} |
|
161 | ||
162 |
#' `AET04` Table 1 (Default) Adverse Events by Highest `NCI` `CTACAE` `AE` Grade Table 1. |
|
163 |
#' |
|
164 |
#' The `AET04` table provides an |
|
165 |
#' overview of adverse event with the highest `NCI` `CTCAE` grade per individual. |
|
166 |
#' |
|
167 |
#' @include chevron_tlg-S4class.R |
|
168 |
#' @export |
|
169 |
#' |
|
170 |
#' @examples |
|
171 |
#' grade_groups <- list( |
|
172 |
#' "Grade 1-2" = c("1", "2"), |
|
173 |
#' "Grade 3-4" = c("3", "4"), |
|
174 |
#' "Grade 5" = c("5") |
|
175 |
#' ) |
|
176 |
#' proc_data <- dunlin::log_filter(syn_data, AEBODSYS == "cl A.1", "adae") |
|
177 |
#' run(aet04, proc_data, grade_groups = grade_groups) |
|
178 |
aet04 <- chevron_t( |
|
179 |
main = aet04_main, |
|
180 |
preprocess = aet04_pre, |
|
181 |
postprocess = aet04_post |
|
182 |
) |
1 |
# ext01 ---- |
|
2 | ||
3 |
#' @describeIn ext01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param summaryvars (`character`) variables to be analyzed. The label attribute of the corresponding column in `adex` |
|
7 |
#' table of `adam_db` is used as label. |
|
8 |
#' @param map (`data.frame`) of mapping for split rows. |
|
9 |
#' @returns the main function returns an `rtables` object. |
|
10 |
#' |
|
11 |
#' @details |
|
12 |
#' * Default Exposure table |
|
13 |
#' * The `n` row provides the number of non-missing values. The percentages for categorical variables is based on `n`. |
|
14 |
#' The percentages for `Total number of patients with at least one dose modification` are based on the number of |
|
15 |
#' patients in the corresponding analysis population given by `N`. |
|
16 |
#' * Split columns by arm, typically `ACTARM`. |
|
17 |
#' * Does not include a total column by default. |
|
18 |
#' * Sorted by alphabetic order of the `PARAM` value. Transform to factor and re-level for custom order. |
|
19 |
#' * `ANL01FL` is not relevant subset. |
|
20 |
#' |
|
21 |
#' @note |
|
22 |
#' * `adam_db` object must contain an `adex` table with columns specified in `summaryvars`. |
|
23 |
#' |
|
24 |
#' @export |
|
25 |
#' |
|
26 |
ext01_main <- function(adam_db, |
|
27 |
arm_var = "ACTARM", |
|
28 |
lbl_overall = NULL, |
|
29 |
summaryvars = "AVAL", |
|
30 |
row_split_var = "PARCAT2", |
|
31 |
page_var = NULL, |
|
32 |
map = NULL, |
|
33 |
...) { |
|
34 | 2x |
assert_all_tablenames(adam_db, c("adsl", "adex")) |
35 | 2x |
assert_string(arm_var) |
36 | 2x |
assert_string(lbl_overall, null.ok = TRUE) |
37 | 2x |
assert_character(summaryvars) |
38 | 2x |
assert_character(row_split_var, null.ok = TRUE) |
39 | 2x |
assert_string(page_var, null.ok = TRUE) |
40 | 2x |
assert_data_frame(map, null.ok = TRUE) |
41 | 2x |
assert_valid_var_pair(adam_db$adsl, adam_db$adex, arm_var) |
42 | 2x |
assert_valid_variable(adam_db$adex, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
43 | 2x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
44 | 2x |
assert_valid_variable(adam_db$adex, summaryvars, empty_ok = TRUE, na_ok = TRUE) |
45 | 2x |
assert_valid_variable( |
46 | 2x |
adam_db$adex, c(row_split_var, "PARAMCD", "PARAM"), |
47 | 2x |
types = list(c("character", "factor")), empty_ok = TRUE |
48 |
) |
|
49 | 2x |
assert_valid_variable(adam_db$adex, colnames(map), types = list(c("character", "factor"))) |
50 | 2x |
if (!is.null(map)) { |
51 | ! |
map <- infer_mapping(map, adam_db$adex) |
52 |
} |
|
53 | 2x |
assert_subset(page_var, c(row_split_var)) |
54 | ||
55 | 2x |
lbl_overall <- render_safe(lbl_overall) |
56 | 2x |
summaryvars_lbls <- var_labels_for(adam_db$adex, summaryvars) |
57 | 2x |
row_split_lbl <- var_labels_for(adam_db$adex, row_split_var) |
58 | ||
59 | 2x |
lyt <- ext01_lyt( |
60 | 2x |
arm_var = arm_var, |
61 | 2x |
lbl_overall = lbl_overall, |
62 | 2x |
summaryvars = summaryvars, |
63 | 2x |
summaryvars_lbls = summaryvars_lbls, |
64 | 2x |
row_split_var = row_split_var, |
65 | 2x |
row_split_lbl = row_split_lbl, |
66 | 2x |
page_var = page_var, |
67 | 2x |
map = map |
68 |
) |
|
69 | ||
70 | 2x |
tbl <- build_table(lyt, adam_db$adex, adam_db$adsl) |
71 | ||
72 | 2x |
tbl |
73 |
} |
|
74 | ||
75 |
#' `ext01` Layout |
|
76 |
#' |
|
77 |
#' @inheritParams gen_args |
|
78 |
#' |
|
79 |
#' @param summaryvars (`character`) the name of the variable to be analyzed. By default `"AVAL"`. |
|
80 |
#' @param summaryvars_lbls (`character`) the label associated with the analyzed variable. |
|
81 |
#' @returns a `PreDataTableLayouts` object. |
|
82 |
#' |
|
83 |
#' @keywords internal |
|
84 |
#' |
|
85 |
ext01_lyt <- function(arm_var, |
|
86 |
lbl_overall, |
|
87 |
summaryvars, |
|
88 |
summaryvars_lbls, |
|
89 |
row_split_var, |
|
90 |
row_split_lbl, |
|
91 |
page_var, |
|
92 |
map) { |
|
93 | 10x |
page_by <- get_page_by(page_var, c(row_split_var)) |
94 | 10x |
label_pos <- ifelse(page_by, "hidden", "topleft") |
95 | 10x |
basic_table(show_colcounts = TRUE) %>% |
96 | 10x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
97 | 10x |
split_rows_by_recursive( |
98 | 10x |
row_split_var, |
99 | 10x |
split_label = row_split_lbl, label_pos = label_pos, page_by = page_by |
100 |
) %>% |
|
101 | 10x |
split_rows_by( |
102 | 10x |
"PARAMCD", |
103 | 10x |
labels_var = "PARAM", |
104 | 10x |
split_fun = split_fun_map(map) |
105 |
) %>% |
|
106 | 10x |
analyze_vars( |
107 | 10x |
vars = summaryvars, |
108 | 10x |
var_labels = summaryvars_lbls, |
109 | 10x |
show_labels = "hidden", |
110 | 10x |
.formats = list(count_fraction = format_count_fraction_fixed_dp) |
111 |
) |
|
112 |
} |
|
113 | ||
114 |
#' @describeIn ext01 Preprocessing |
|
115 |
#' |
|
116 |
#' @inheritParams gen_args |
|
117 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
118 |
#' |
|
119 |
#' @export |
|
120 |
#' |
|
121 |
ext01_pre <- function(adam_db, |
|
122 |
...) { |
|
123 | 2x |
adam_db$adex <- adam_db$adex %>% |
124 | 2x |
filter(.data$PARCAT1 == "OVERALL") %>% |
125 | 2x |
filter(.data$PARAMCD %in% c("TDURD", "TDOSE")) |
126 | ||
127 | 2x |
adam_db |
128 |
} |
|
129 | ||
130 |
#' @describeIn ext01 Postprocessing |
|
131 |
#' |
|
132 |
#' @inheritParams gen_args |
|
133 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
134 |
#' @export |
|
135 |
#' |
|
136 |
ext01_post <- function(tlg, prune_0 = TRUE, ...) { |
|
137 | 2x |
if (prune_0) tlg <- smart_prune(tlg) |
138 | 2x |
std_postprocessing(tlg) |
139 |
} |
|
140 | ||
141 |
#' `EXT01` Exposure Summary Table. |
|
142 |
#' |
|
143 |
#' The `EXT01` table provides an overview of the of the exposure of the |
|
144 |
#' patients in terms of Total dose administered or missed, and treatment duration. |
|
145 |
#' |
|
146 |
#' @include chevron_tlg-S4class.R |
|
147 |
#' @export |
|
148 |
#' |
|
149 |
#' @examples |
|
150 |
#' run(ext01, syn_data) |
|
151 |
#' |
|
152 |
#' run(ext01, syn_data, summaryvars = c("AVAL", "AVALCAT1"), prune_0 = FALSE) |
|
153 |
#' |
|
154 |
#' levels(syn_data$adex$AVALCAT1) <- c(levels(syn_data$adex$AVALCAT1), "12 months") |
|
155 |
#' map <- data.frame( |
|
156 |
#' PARAMCD = "TDURD", |
|
157 |
#' AVALCAT1 = c("< 1 month", "1 to <3 months", ">=6 months", "3 to <6 months", "12 months") |
|
158 |
#' ) |
|
159 |
#' run(ext01, syn_data, summaryvars = c("AVAL", "AVALCAT1"), prune_0 = FALSE, map = map) |
|
160 |
ext01 <- chevron_t( |
|
161 |
main = ext01_main, |
|
162 |
preprocess = ext01_pre, |
|
163 |
postprocess = ext01_post |
|
164 |
) |
1 |
# dtht01 ---- |
|
2 | ||
3 |
#' @describeIn dtht01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param time_since_last_dose (`flag`) should the time to event information be displayed. |
|
7 |
#' @param other_category (`flag`) should the breakdown of the `OTHER` category be displayed. |
|
8 |
#' @returns the main function returns an `rtables` object. |
|
9 |
#' |
|
10 |
#' @details |
|
11 |
#' * Numbers represent absolute numbers of subjects and fraction of `N`, or absolute numbers when specified. |
|
12 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
13 |
#' * Does not include a total column by default. |
|
14 |
#' |
|
15 |
#' @note |
|
16 |
#' * `adam_db` object must contain an `adsl` table with the columns `"DTHFL"`, `"DTHCAT"` as well as `LDDTHGR1` if |
|
17 |
#' `time_since_last_dose` is `TRUE`. |
|
18 |
#' |
|
19 |
#' @export |
|
20 |
dtht01_main <- function(adam_db, |
|
21 |
arm_var = "ACTARM", |
|
22 |
lbl_overall = NULL, |
|
23 |
other_category = FALSE, |
|
24 |
time_since_last_dose = FALSE, |
|
25 |
...) { |
|
26 | 2x |
assert_all_tablenames(adam_db, "adsl") |
27 | 2x |
assert_string(arm_var) |
28 | 2x |
assert_string(lbl_overall, null.ok = TRUE) |
29 | 2x |
assert_flag(other_category) |
30 | 2x |
assert_flag(time_since_last_dose, null.ok = TRUE) |
31 | 2x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list("character", "factor")) |
32 | 2x |
assert_valid_variable( |
33 | 2x |
adam_db$adsl, |
34 | 2x |
"DTHFL", |
35 | 2x |
types = list("character", "factor"), na_ok = TRUE, min_chars = 0L |
36 |
) |
|
37 | ||
38 | 2x |
lbl_overall <- render_safe(lbl_overall) |
39 | 2x |
other_var <- if (other_category) "DTHCAUS" |
40 | 2x |
dose_death_var <- if (time_since_last_dose) "LDDTHGR1" |
41 | ||
42 | 2x |
assert_valid_variable( |
43 | 2x |
adam_db$adsl, |
44 | 2x |
c("DTHCAT", other_var, dose_death_var), |
45 | 2x |
types = list("character", "factor"), na_ok = TRUE, min_chars = 1L |
46 |
) |
|
47 | ||
48 | 2x |
if (other_category) { |
49 | 1x |
death_cause <- lvls(adam_db$adsl$DTHCAT) |
50 | 1x |
if (length(death_cause) == 0L) { |
51 | ! |
stop("other_category specified but could not find any level in `DTHCAT`!") |
52 |
} |
|
53 | 1x |
other_level <- death_cause[length(death_cause)] |
54 | 1x |
if (toupper(other_level) != "OTHER") { |
55 | ! |
warning( |
56 | ! |
"You included detailed information for Other, however the last level of ", |
57 | ! |
" `adam_db$adsl$DTHCAT` looks like not `Other`.", |
58 | ! |
call. = FALSE |
59 |
) |
|
60 |
} |
|
61 |
} |
|
62 | ||
63 | 2x |
lyt <- dtht01_lyt( |
64 | 2x |
arm_var = arm_var, |
65 | 2x |
lbl_overall = lbl_overall, |
66 | 2x |
death_flag = "DTHFL", |
67 | 2x |
death_var = "DTHCAT", |
68 | 2x |
other_level = other_level, |
69 | 2x |
other_var = other_var, |
70 | 2x |
dose_death_var = dose_death_var |
71 |
) |
|
72 | ||
73 | 2x |
adsl <- adam_db$adsl %>% |
74 | 2x |
mutate(TOTAL = "Primary Cause of Death") |
75 | ||
76 | 2x |
build_table(lyt, adsl) |
77 |
} |
|
78 | ||
79 |
#' `dtht01` Layout |
|
80 |
#' |
|
81 |
#' @inheritParams dtht01_main |
|
82 |
#' @param death_flag (`string`) variable name of death flag. |
|
83 |
#' @param death_var (`string`) variable name of death category. |
|
84 |
#' @param other_level (`string`) `"Other"` level in death category. |
|
85 |
#' @param other_var (`string`) variable name of death cause under `"Other"`. |
|
86 |
#' @param dose_death_var (`string`) variable name of the days from last dose. |
|
87 |
#' @returns a `PreDataTableLayouts` object. |
|
88 |
#' |
|
89 |
#' @keywords internal |
|
90 |
#' |
|
91 |
dtht01_lyt <- function(arm_var, |
|
92 |
lbl_overall, |
|
93 |
death_flag, |
|
94 |
death_var, |
|
95 |
other_level, |
|
96 |
other_var, |
|
97 |
dose_death_var) { |
|
98 | 5x |
if (is.null(dose_death_var) && is.null(other_var)) { |
99 | 3x |
lyt_block_fun <- analyze |
100 |
} else { |
|
101 | 2x |
lyt_block_fun <- summarize_row |
102 |
} |
|
103 | 5x |
lyt <- basic_table(show_colcounts = TRUE) %>% |
104 | 5x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
105 | 5x |
count_values( |
106 | 5x |
death_flag, |
107 | 5x |
values = "Y", |
108 | 5x |
.labels = c(count_fraction = "Total number of deaths"), |
109 | 5x |
.formats = c(count_fraction = format_count_fraction_fixed_dp) |
110 |
) %>% |
|
111 | 5x |
split_rows_by("TOTAL", child_labels = "visible", label_pos = "hidden", split_fun = drop_split_levels) %>% |
112 | 5x |
lyt_block_fun( |
113 | 5x |
death_var, |
114 | 5x |
make_afun( |
115 | 5x |
s_summary_na, |
116 | 5x |
.stats = c("n", "count_fraction"), .ungroup_stats = "count_fraction", |
117 | 5x |
.formats = list(n = "xx", count_fraction = format_count_fraction_fixed_dp) |
118 |
), |
|
119 | 5x |
indent_mod = 0L |
120 |
) |
|
121 | 5x |
if (!is.null(other_var)) { |
122 | 2x |
lyt <- lyt %>% |
123 | 2x |
split_rows_by(death_var, split_fun = keep_split_levels(other_level), child_labels = "hidden") %>% |
124 | 2x |
analyze_vars(other_var, .stats = "count_fraction", denom = "N_row") |
125 |
} |
|
126 | 5x |
if (!is.null(dose_death_var)) { |
127 | 2x |
lyt <- lyt %>% |
128 | 2x |
summarize_vars_allow_na( |
129 | 2x |
vars = dose_death_var, |
130 | 2x |
var_labels = "Days from last drug administration", |
131 | 2x |
.formats = list(count_fraction = format_count_fraction_fixed_dp), |
132 | 2x |
show_labels = "visible", |
133 | 2x |
nested = FALSE, |
134 | 2x |
inclNAs = FALSE |
135 |
) %>% |
|
136 | 2x |
split_rows_by( |
137 | 2x |
dose_death_var, |
138 | 2x |
split_fun = drop_split_levels, |
139 | 2x |
split_label = "Primary cause by days from last study drug administration", |
140 | 2x |
label_pos = "visible", |
141 | 2x |
nested = FALSE |
142 |
) %>% |
|
143 | 2x |
summarize_vars_allow_na( |
144 | 2x |
death_var, |
145 | 2x |
.formats = list(count_fraction = format_count_fraction_fixed_dp) |
146 |
) |
|
147 |
} |
|
148 | ||
149 | 5x |
lyt |
150 |
} |
|
151 | ||
152 |
#' @describeIn dtht01 Preprocessing |
|
153 |
#' |
|
154 |
#' @inheritParams gen_args |
|
155 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
156 |
#' @export |
|
157 |
#' |
|
158 |
dtht01_pre <- function(adam_db, ...) { |
|
159 | 2x |
death_format <- rule( |
160 | 2x |
"Adverse Event" = "ADVERSE EVENT", |
161 | 2x |
"Progressive Disease" = "PROGRESSIVE DISEASE", |
162 | 2x |
"Other" = "OTHER" |
163 |
) |
|
164 | ||
165 | 2x |
adam_db$adsl <- adam_db$adsl %>% |
166 | 2x |
mutate( |
167 | 2x |
DTHCAT = reformat(.data$DTHCAT, death_format) |
168 |
) |
|
169 | ||
170 | 2x |
adam_db |
171 |
} |
|
172 | ||
173 |
#' @describeIn dtht01 Postprocessing |
|
174 |
#' |
|
175 |
#' @inheritParams gen_args |
|
176 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
177 |
#' @export |
|
178 |
#' |
|
179 |
dtht01_post <- function(tlg, prune_0 = TRUE, ...) { |
|
180 | 2x |
if (prune_0) { |
181 | 2x |
tlg <- smart_prune(tlg) |
182 |
} |
|
183 | 2x |
std_postprocessing(tlg) |
184 |
} |
|
185 | ||
186 |
#' `DTHT01` Table 1 (Default) Death Table. |
|
187 |
#' |
|
188 |
#' A description of the causes of death optionally with the breakdown of the |
|
189 |
#' `OTHER` category and/or post-study reporting of death. |
|
190 |
#' |
|
191 |
#' @include chevron_tlg-S4class.R |
|
192 |
#' @export |
|
193 |
#' |
|
194 |
#' @examples |
|
195 |
#' run(dtht01, syn_data) |
|
196 |
#' |
|
197 |
#' run(dtht01, syn_data, other_category = TRUE, time_since_last_dose = TRUE) |
|
198 |
dtht01 <- chevron_t( |
|
199 |
main = dtht01_main, |
|
200 |
preprocess = dtht01_pre, |
|
201 |
postprocess = dtht01_post |
|
202 |
) |
1 |
# egt03 ---- |
|
2 |
#' @describeIn egt03 Main TLG function |
|
3 |
#' |
|
4 |
#' @param arm_var (`character`) the arm variables used for row split, typically `"ACTARMCD"`. |
|
5 |
#' @param summaryvar (`character`) variables to be analyzed, typically `"BNRIND"`. Labels of the corresponding columns |
|
6 |
#' are used as subtitles. |
|
7 |
#' @param splitvar (`character`) variables to be analyzed, typically `"ANRIND"`. Labels of the corresponding columns are |
|
8 |
#' used as subtitles. |
|
9 |
#' @returns the main function returns an `rtables` object. |
|
10 |
#' |
|
11 |
#' @details |
|
12 |
#' * `ADEG` data are subsetted to contain only "POST-BASELINE MINIMUM"/"POST-BASELINE MAXIMUM" visit |
|
13 |
#' according to the preprocessing. |
|
14 |
#' * Percentages are based on the total number of patients in a treatment group. |
|
15 |
#' * Split columns by Analysis Reference Range Indicator, typically `ANRIND`. |
|
16 |
#' * Does not include a total column by default. |
|
17 |
#' * Sorted based on factor level. |
|
18 |
#' |
|
19 |
#' @note |
|
20 |
#' * `adam_db` object must contain an `adeg` table with a `"ACTARMCD"` column as well as columns specified in |
|
21 |
#' `summaryvar` and `splitvar`. |
|
22 |
#' |
|
23 |
#' @export |
|
24 |
#' |
|
25 |
egt03_main <- function(adam_db, |
|
26 |
arm_var = "ACTARMCD", |
|
27 |
summaryvar = "BNRIND", |
|
28 |
splitvar = "ANRIND", |
|
29 |
visitvar = "AVISIT", |
|
30 |
page_var = "PARAMCD", |
|
31 |
...) { |
|
32 | 1x |
assert_all_tablenames(adam_db, c("adsl", "adeg")) |
33 | 1x |
assert_string(arm_var) |
34 | 1x |
assert_string(summaryvar) |
35 | 1x |
assert_string(splitvar) |
36 | 1x |
assert_string(visitvar) |
37 | 1x |
assert_string(page_var, null.ok = TRUE) |
38 | 1x |
assert_subset(page_var, "PARAMCD") |
39 | 1x |
assert_valid_variable(adam_db$adeg, summaryvar, types = list("character", "factor")) |
40 | 1x |
assert_valid_variable(adam_db$adeg, c("PARAMCD", "PARAM", splitvar), types = list("character", "factor")) |
41 | 1x |
assert_single_value(adam_db$adeg[[visitvar]]) |
42 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adeg, arm_var) |
43 | 1x |
assert_valid_variable(adam_db$adeg, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
44 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
45 | ||
46 | 1x |
lbl_armvar <- var_labels_for(adam_db$adeg, arm_var) |
47 | 1x |
lbl_summaryvars <- var_labels_for(adam_db$adeg, summaryvar) |
48 | 1x |
lbl_splitvar <- var_labels_for(adam_db$adeg, splitvar) |
49 | 1x |
lbl_param <- var_labels_for(adam_db$adeg, "PARAM") |
50 | ||
51 | 1x |
lyt <- egt03_lyt( |
52 | 1x |
arm_var = arm_var, |
53 | 1x |
splitvar = splitvar, |
54 | 1x |
summaryvar = summaryvar, |
55 | 1x |
lbl_armvar = lbl_armvar, |
56 | 1x |
lbl_summaryvars = lbl_summaryvars, |
57 | 1x |
lbl_param = lbl_param, |
58 | 1x |
page_var = page_var |
59 |
) |
|
60 | 1x |
adam_db$adeg$SPLIT_LABEL <- factor(rep(lbl_splitvar, nrow(adam_db$adeg)), levels = lbl_splitvar) |
61 | ||
62 | 1x |
tbl <- build_table( |
63 | 1x |
lyt, |
64 | 1x |
df = adam_db$adeg |
65 |
) |
|
66 | ||
67 | 1x |
tbl |
68 |
} |
|
69 | ||
70 |
#' `egt03` Layout |
|
71 |
#' |
|
72 |
#' @inheritParams gen_args |
|
73 |
#' @inheritParams egt03_main |
|
74 |
#' |
|
75 |
#' @param lbl_armvar (`string`) label of the `arm_var` variable. |
|
76 |
#' @param lbl_summaryvars (`string`) label of the `summaryvar` variable. |
|
77 |
#' @returns a `PreDataTableLayouts` object. |
|
78 |
#' |
|
79 |
#' @keywords internal |
|
80 |
#' |
|
81 |
egt03_lyt <- function(arm_var, |
|
82 |
splitvar, |
|
83 |
summaryvar, |
|
84 |
lbl_armvar, |
|
85 |
lbl_summaryvars, |
|
86 |
lbl_param, |
|
87 |
page_var) { |
|
88 | 3x |
page_by <- !is.null(page_var) |
89 | 3x |
indent <- 2L |
90 | 3x |
space <- stringr::str_dup(" ", indent * (1L + !page_by)) |
91 | 3x |
lbl_summaryvars <- paste0(space, lbl_summaryvars) |
92 | ||
93 | 3x |
basic_table(show_colcounts = FALSE) %>% |
94 | 3x |
split_cols_by("SPLIT_LABEL") %>% |
95 | 3x |
split_cols_by(splitvar) %>% |
96 | 3x |
split_rows_by( |
97 | 3x |
"PARAMCD", |
98 | 3x |
labels_var = "PARAM", |
99 | 3x |
page_by = page_by, |
100 | 3x |
split_fun = drop_split_levels, |
101 | 3x |
split_label = lbl_param, |
102 | 3x |
label_pos = if (page_by) "hidden" else "topleft" |
103 |
) %>% |
|
104 | 3x |
split_rows_by(arm_var, |
105 | 3x |
split_fun = drop_split_levels, |
106 | 3x |
label_pos = "topleft", |
107 | 3x |
split_label = lbl_armvar |
108 |
) %>% |
|
109 | 3x |
add_rowcounts() %>% |
110 | 3x |
analyze_vars( |
111 | 3x |
summaryvar, |
112 | 3x |
denom = "N_row", .stats = "count_fraction", |
113 | 3x |
.formats = list(count_fraction = format_count_fraction_fixed_dp) |
114 |
) %>% |
|
115 | 3x |
append_topleft(lbl_summaryvars) |
116 |
} |
|
117 | ||
118 |
#' @describeIn egt03 Preprocessing |
|
119 |
#' |
|
120 |
#' @inheritParams gen_args |
|
121 |
#' @inheritParams egt03_main |
|
122 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
123 |
#' |
|
124 |
#' @export |
|
125 |
#' |
|
126 |
egt03_pre <- function(adam_db, ...) { |
|
127 | 1x |
adam_db$adeg <- adam_db$adeg %>% |
128 | 1x |
filter( |
129 | 1x |
.data$AVISIT == "POST-BASELINE MINIMUM" |
130 |
) %>% |
|
131 | 1x |
mutate(BNRIND = factor( |
132 | 1x |
.data$BNRIND, |
133 | 1x |
levels = c("LOW", "NORMAL", "HIGH", "Missing"), |
134 | 1x |
labels = c("LOW", "NORMAL", "HIGH", "Missing") |
135 |
)) %>% |
|
136 | 1x |
mutate(ANRIND = factor( |
137 | 1x |
.data$ANRIND, |
138 | 1x |
levels = c("LOW", "NORMAL", "HIGH", "Missing"), |
139 | 1x |
labels = c("LOW", "NORMAL", "HIGH", "Missing") |
140 |
)) %>% |
|
141 | 1x |
mutate( |
142 | 1x |
BNRIND = with_label(.data$BNRIND, "Baseline Reference Range Indicator"), |
143 | 1x |
ANRIND = with_label(.data$ANRIND, "Minimum Post-Baseline Assessment") |
144 |
) |
|
145 | ||
146 | 1x |
adam_db |
147 |
} |
|
148 | ||
149 |
#' @describeIn egt03 Postprocessing |
|
150 |
#' |
|
151 |
#' @inheritParams gen_args |
|
152 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
153 |
#' |
|
154 |
#' @export |
|
155 |
#' |
|
156 |
egt03_post <- function(tlg, prune_0 = FALSE, ...) { |
|
157 | ! |
if (prune_0) tlg <- smart_prune(tlg) |
158 | ||
159 | 1x |
std_postprocessing(tlg) |
160 |
} |
|
161 | ||
162 |
#' `EGT03` Shift Table of ECG Interval Data - Baseline versus Minimum or Maximum Post-Baseline. |
|
163 |
#' |
|
164 |
#' The `EGT03` Table entries provide the number of patients by baseline assessment and minimum or maximum post-baseline |
|
165 |
#' assessment. Percentages are based on the total number of patients in a treatment group. Baseline is the patient's |
|
166 |
#' last observation prior to initiation of study drug. |
|
167 |
#' |
|
168 |
#' @include chevron_tlg-S4class.R |
|
169 |
#' @export |
|
170 |
#' |
|
171 |
#' @examples |
|
172 |
#' library(dunlin) |
|
173 |
#' |
|
174 |
#' proc_data <- log_filter(syn_data, PARAMCD == "HR", "adeg") |
|
175 |
#' run(egt03, proc_data) |
|
176 |
egt03 <- chevron_t( |
|
177 |
main = egt03_main, |
|
178 |
preprocess = egt03_pre, |
|
179 |
postprocess = egt03_post |
|
180 |
) |
1 |
# lbt14 ---- |
|
2 | ||
3 |
#' @describeIn lbt14 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param gr_missing (`string`) how missing baseline grades should be handled. Defaults to `"incl"` to include the |
|
7 |
#' `"Missing"` |
|
8 |
#' level. Other options are `"excl"` to exclude patients with missing baseline grades and `"gr_0"` to convert missing |
|
9 |
#' baseline grades to grade 0. |
|
10 |
#' @param direction (`string`) one of `"high"` or `"low"` indicating which shift direction should be detailed. |
|
11 |
#' @returns the main function returns an `rtables` object. |
|
12 |
#' |
|
13 |
#' @details |
|
14 |
#' * This table follows ADaMIG v1.1. |
|
15 |
#' * Only the worst grade recorded for each patient is included in the table. |
|
16 |
#' * If no missing baseline lab results, the "Missing" level of `BTOXGR` is excluded. |
|
17 |
#' * Grading takes value from -4 to 4, negative value means the abnormality direction is low, |
|
18 |
#' positive value means the abnormality direction is high. |
|
19 |
#' * Grades 0, 1, 2, 3, and 4 are counted as `"Not Low"` when `direction = "low"`. Conversely, when `direction = |
|
20 |
#' "high"`, Grades 0, -1, -2, -3, and -4 are counted as `"Not High". |
|
21 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
22 |
#' * Split columns by arm, typically `ACTARM`. |
|
23 |
#' |
|
24 |
#' @note |
|
25 |
#' * `adam_db` object must contain an `adlb` table with columns `"USUBJID"`, `"PARAM"`, `"BTOXGR"`, `"ATOXGR"`, |
|
26 |
#' and the column specified by `arm_var`. |
|
27 |
#' |
|
28 |
#' @export |
|
29 |
#' |
|
30 |
lbt14_main <- function(adam_db, |
|
31 |
arm_var = "ACTARM", |
|
32 |
lbl_overall = NULL, |
|
33 |
gr_missing = "incl", |
|
34 |
page_var = "PARAMCD", |
|
35 |
...) { |
|
36 | 4x |
assert_all_tablenames(adam_db, c("adsl", "adlb")) |
37 | 4x |
assert_string(arm_var) |
38 | 4x |
assert_string(lbl_overall, null.ok = TRUE) |
39 | 4x |
assert_choice(gr_missing, c("incl", "excl", "gr_0")) |
40 | 4x |
assert_subset(page_var, "PARAMCD") |
41 | 4x |
assert_valid_variable(adam_db$adlb, c("ATOXGR", "BTOXGR"), types = list("factor"), na_ok = TRUE) |
42 | 4x |
assert_valid_variable(adam_db$adlb, c("PARAMCD", "PARAM"), types = list(c("character", "factor")), na_ok = FALSE) |
43 | 4x |
assert_valid_variable(adam_db$adlb, c("USUBJID"), types = list(c("character", "factor")), empty_ok = TRUE) |
44 | 4x |
assert_valid_variable(adam_db$adsl, c("USUBJID"), types = list(c("character", "factor"))) |
45 | 4x |
assert_valid_var_pair(adam_db$adsl, adam_db$adlb, arm_var) |
46 | ||
47 | 4x |
lbl_overall <- render_safe(lbl_overall) |
48 | 4x |
lbl_param <- var_labels_for(adam_db$adlb, "PARAM") |
49 | 4x |
lbl_btoxgr <- var_labels_for(adam_db$adlb, "BTOXGR") |
50 | ||
51 | 4x |
lyt <- lbt14_lyt( |
52 | 4x |
arm_var = arm_var, |
53 | 4x |
lbl_overall = lbl_overall, |
54 | 4x |
lbl_param = lbl_param, |
55 | 4x |
lbl_btoxgr = lbl_btoxgr, |
56 | 4x |
page_var = page_var |
57 |
) |
|
58 | ||
59 | 4x |
tbl <- build_table(lyt, adam_db$adlb, alt_counts_df = adam_db$adsl) |
60 | ||
61 | 4x |
tbl |
62 |
} |
|
63 | ||
64 |
#' `lbt14` Layout |
|
65 |
#' |
|
66 |
#' @inheritParams lbt14_main |
|
67 |
#' |
|
68 |
#' @keywords internal |
|
69 |
#' |
|
70 |
lbt14_lyt <- function(arm_var, |
|
71 |
lbl_overall, |
|
72 |
lbl_param, |
|
73 |
lbl_btoxgr, |
|
74 |
page_var) { |
|
75 | 14x |
page_by <- !is.null(page_var) |
76 | 14x |
label_pos <- ifelse(page_by, "hidden", "topleft") |
77 | 14x |
basic_table(show_colcounts = TRUE) %>% |
78 | 14x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
79 | 14x |
split_rows_by( |
80 | 14x |
var = "PARAMCD", |
81 | 14x |
labels_var = "PARAM", |
82 | 14x |
split_fun = drop_split_levels, |
83 | 14x |
label_pos = label_pos, |
84 | 14x |
split_label = lbl_param, |
85 | 14x |
page_by = page_by |
86 |
) %>% |
|
87 | 14x |
split_rows_by( |
88 | 14x |
"BTOXGR", |
89 | 14x |
label_pos = "topleft", |
90 | 14x |
split_label = lbl_btoxgr |
91 |
) %>% |
|
92 | 14x |
summarize_num_patients(var = "USUBJID", .stats = c("unique_count"), unique_count_suffix = FALSE) %>% |
93 | 14x |
count_occurrences_by_grade("ATOXGR", denom = "n", drop = FALSE, .indent_mods = 3L) %>% |
94 | 14x |
append_topleft(paste0(stringr::str_dup(" ", 2L * (5L - page_by)), "Post-baseline NCI-CTCAE Grade")) |
95 |
} |
|
96 | ||
97 |
#' @describeIn lbt14 Preprocessing |
|
98 |
#' |
|
99 |
#' @inheritParams gen_args |
|
100 |
#' @inheritParams lbt14_main |
|
101 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
102 |
#' @export |
|
103 |
#' |
|
104 |
lbt14_pre <- function(adam_db, |
|
105 |
gr_missing = "incl", |
|
106 |
direction = "low", |
|
107 |
...) { |
|
108 | 4x |
if (identical(direction, "high")) { |
109 | 1x |
adam_db$adlb <- adam_db$adlb %>% |
110 | 1x |
filter(.data$WGRHIFL == "Y") %>% |
111 | 1x |
h_adsl_adlb_merge_using_worst_flag( |
112 | 1x |
adsl = adam_db$adsl, |
113 | 1x |
worst_flag = c("WGRHIFL" = "Y") |
114 |
) |
|
115 | 3x |
} else if (identical(direction, "low")) { |
116 | 3x |
adam_db$adlb <- adam_db$adlb %>% |
117 | 3x |
filter(.data$WGRLOFL == "Y") %>% |
118 | 3x |
h_adsl_adlb_merge_using_worst_flag( |
119 | 3x |
adsl = adam_db$adsl, |
120 | 3x |
worst_flag = c("WGRLOFL" = "Y") |
121 |
) |
|
122 |
} |
|
123 | ||
124 | 4x |
grade_rule <- get_grade_rule(direction, gr_missing) |
125 | 4x |
adam_db$adlb <- adam_db$adlb %>% |
126 | 4x |
mutate( |
127 | 4x |
across(all_of(c("BTOXGR", "ATOXGR")), ~ reformat(.x, grade_rule)) |
128 |
) |
|
129 | ||
130 | 4x |
adam_db |
131 |
} |
|
132 | ||
133 |
#' @describeIn lbt14 Postprocessing |
|
134 |
#' |
|
135 |
#' @inheritParams gen_args |
|
136 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
137 |
#' @export |
|
138 |
#' |
|
139 |
lbt14_post <- function(tlg, prune_0 = TRUE, ...) { |
|
140 | 4x |
if (prune_0) tlg <- tlg %>% trim_rows() |
141 | 4x |
std_postprocessing(tlg) |
142 |
} |
|
143 | ||
144 |
#' `LBT14` Laboratory Test Results Shift Table – Highest `NCI-CTCAE` Grade Post-Baseline by |
|
145 |
#' Baseline Grade (Low or High Direction). |
|
146 |
#' |
|
147 |
#' @include chevron_tlg-S4class.R |
|
148 |
#' @export |
|
149 |
#' |
|
150 |
#' @examples |
|
151 |
#' run(lbt14, syn_data) |
|
152 |
lbt14 <- chevron_t( |
|
153 |
main = lbt14_main, |
|
154 |
preprocess = lbt14_pre, |
|
155 |
postprocess = lbt14_post |
|
156 |
) |
1 |
# pdt02 ---- |
|
2 | ||
3 |
#' @describeIn pdt02 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param dvreas_var (`string`) the variable defining the reason for deviation. By default `DVREAS`. |
|
7 |
#' @param dvterm_var (`string`) the variable defining the protocol deviation term. By default `DVTERM`. |
|
8 |
#' |
|
9 |
#' @details |
|
10 |
#' * Data should be filtered for major protocol deviations related to epidemic/pandemic. |
|
11 |
#' `(AEPRELFL == "Y" & DVCAT == "MAJOR")`. |
|
12 |
#' * Numbers represent absolute numbers of subjects and fraction of `N`, or absolute numbers when specified. |
|
13 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
14 |
#' * Split columns by arm. |
|
15 |
#' * Does not include a total column by default. |
|
16 |
#' * Sort by deviation reason alphabetically and within deviation reason by decreasing total number of patients with |
|
17 |
#' the specific deviation term. |
|
18 |
#' |
|
19 |
#' @note |
|
20 |
#' * `adam_db` object must contain an `addv` table with the columns specified in `dvreas_var` and `dvterm_var`. |
|
21 |
#' |
|
22 |
#' @export |
|
23 |
#' |
|
24 |
pdt02_main <- function(adam_db, |
|
25 |
arm_var = "ARM", |
|
26 |
lbl_overall = NULL, |
|
27 |
dvreas_var = "DVREAS", |
|
28 |
dvterm_var = "DVTERM", |
|
29 |
...) { |
|
30 | 1x |
assert_all_tablenames(adam_db, c("adsl", "addv")) |
31 | 1x |
assert_string(arm_var) |
32 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
33 | 1x |
assert_string(dvreas_var) |
34 | 1x |
assert_string(dvterm_var) |
35 | 1x |
assert_valid_variable(adam_db$addv, c(dvreas_var, dvterm_var), types = list(c("character", "factor"))) |
36 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
37 | 1x |
assert_valid_variable(adam_db$addv, "USUBJID", types = list(c("character", "factor")), empty_ok = TRUE) |
38 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$addv, arm_var) |
39 | ||
40 | 1x |
lbl_overall <- render_safe(lbl_overall) |
41 | 1x |
lbl_dvreas_var <- var_labels_for(adam_db$addv, dvreas_var) |
42 | 1x |
lbl_dvterm_var <- var_labels_for(adam_db$addv, dvterm_var) |
43 | ||
44 | 1x |
lyt <- pdt02_lyt( |
45 | 1x |
arm_var = arm_var, |
46 | 1x |
lbl_overall = lbl_overall, |
47 | 1x |
lbl_dvreas_var = lbl_dvreas_var, |
48 | 1x |
lbl_dvterm_var = lbl_dvterm_var, |
49 | 1x |
dvreas_var = dvreas_var, |
50 | 1x |
dvterm_var = dvterm_var |
51 |
) |
|
52 | ||
53 | 1x |
tbl <- build_table(lyt, adam_db$addv, alt_counts_df = adam_db$adsl) |
54 | ||
55 | 1x |
tbl |
56 |
} |
|
57 | ||
58 |
#' `pdt02` Layout |
|
59 |
#' |
|
60 |
#' @inheritParams gen_args |
|
61 |
#' @inheritParams pdt02_main |
|
62 |
#' @param lbl_dvreas_var (`string`) label for the variable defining the reason for deviation. |
|
63 |
#' @param lbl_dvterm_var (`string`) label for the variable defining the protocol deviation term. |
|
64 |
#' |
|
65 |
#' @keywords internal |
|
66 |
#' |
|
67 |
pdt02_lyt <- function(arm_var, |
|
68 |
lbl_overall, |
|
69 |
lbl_dvreas_var, |
|
70 |
lbl_dvterm_var, |
|
71 |
dvreas_var, |
|
72 |
dvterm_var) { |
|
73 | 3x |
basic_table(show_colcounts = TRUE) %>% |
74 | 3x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
75 | 3x |
analyze_num_patients( |
76 | 3x |
vars = "USUBJID", |
77 | 3x |
.stats = c("unique", "nonunique"), |
78 | 3x |
.labels = c( |
79 | 3x |
unique = render_safe( |
80 | 3x |
"Total number of {patient_label} with at least one major protocol deviation related to epidemic/pandemic" |
81 |
), |
|
82 | 3x |
nonunique = "Total number of major protocol deviations related to epidemic/pandemic" |
83 |
) |
|
84 |
) %>% |
|
85 | 3x |
split_rows_by( |
86 | 3x |
dvreas_var, |
87 | 3x |
nested = FALSE, |
88 | 3x |
split_fun = drop_split_levels, |
89 | 3x |
label_pos = "topleft", |
90 | 3x |
split_label = lbl_dvreas_var |
91 |
) %>% |
|
92 | 3x |
summarize_num_patients( |
93 | 3x |
var = "USUBJID", |
94 | 3x |
.stats = "unique", |
95 | 3x |
.labels = NULL |
96 |
) %>% |
|
97 | 3x |
count_occurrences( |
98 | 3x |
vars = dvterm_var, |
99 | 3x |
id = "USUBJID" |
100 |
) %>% |
|
101 | 3x |
append_topleft(paste(" ", lbl_dvterm_var)) |
102 |
} |
|
103 | ||
104 |
#' @describeIn pdt02 Preprocessing |
|
105 |
#' |
|
106 |
#' @inheritParams pdt02_main |
|
107 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
108 |
#' @export |
|
109 |
#' |
|
110 |
pdt02_pre <- function(adam_db, |
|
111 |
...) { |
|
112 | 1x |
adam_db$addv <- adam_db$addv %>% |
113 | 1x |
mutate(across(all_of(c("DVCAT", "AEPRELFL")), ~ reformat(.x, missing_rule))) %>% |
114 | 1x |
filter(.data$DVCAT == "MAJOR" & .data$AEPRELFL == "Y") %>% |
115 | 1x |
mutate(across(all_of(c("DVREAS", "DVTERM")), ~ reformat(.x, nocoding))) %>% |
116 | 1x |
mutate( |
117 | 1x |
DVREAS = with_label(.data$DVREAS, "Primary Reason"), |
118 | 1x |
DVTERM = with_label(.data$DVTERM, "Description") |
119 |
) |
|
120 | ||
121 | 1x |
adam_db |
122 |
} |
|
123 | ||
124 |
#' @describeIn pdt02 Postprocessing |
|
125 |
#' |
|
126 |
#' @inheritParams pdt02_main |
|
127 |
#' @inheritParams gen_args |
|
128 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
129 |
#' @export |
|
130 |
#' |
|
131 |
pdt02_post <- function(tlg, prune_0 = TRUE, dvreas_var = "DVREAS", dvterm_var = "DVTERM", ...) { |
|
132 | 1x |
if (prune_0) { |
133 | 1x |
tlg <- smart_prune(tlg) |
134 |
} |
|
135 | ||
136 | 1x |
tbl_sorted <- tlg %>% |
137 | 1x |
sort_at_path( |
138 | 1x |
path = c(dvreas_var, "*", dvterm_var), |
139 | 1x |
scorefun = score_occurrences |
140 |
) |
|
141 | ||
142 | 1x |
std_postprocessing(tbl_sorted) |
143 |
} |
|
144 | ||
145 |
#' `pdt02` Major Protocol Deviations Related to Epidemic/Pandemic Table. |
|
146 |
#' |
|
147 |
#' A major protocol deviations |
|
148 |
#' table with the number of subjects and the total number of Major Protocol Deviations Related |
|
149 |
#' to Epidemic/Pandemic sorted alphabetically and deviations name sorted by frequencies. |
|
150 |
#' |
|
151 |
#' @include chevron_tlg-S4class.R |
|
152 |
#' @export |
|
153 |
#' |
|
154 |
#' @examples |
|
155 |
#' run(pdt02, syn_data) |
|
156 |
pdt02 <- chevron_t( |
|
157 |
main = pdt02_main, |
|
158 |
preprocess = pdt02_pre, |
|
159 |
postprocess = pdt02_post |
|
160 |
) |
1 |
#' Creates `NULL` Report |
|
2 |
#' |
|
3 |
#' @param tlg to convert to null report. |
|
4 |
#' @param ind (`integer`) indentation for the outputs of class `VTableTree`. |
|
5 |
#' @param ... not used. |
|
6 |
#' |
|
7 |
#' @rdname report_null |
|
8 |
#' @name report_null |
|
9 |
#' |
|
10 |
#' @returns the `tlg` object or a `NULL` report if the `tlg` is `NULL`, is a `TableTree` with 0 rows, is a `listing_df` |
|
11 |
#' with 0 rows or is a `list` with 0 elements. |
|
12 |
#' |
|
13 |
#' @export |
|
14 |
#' @examples |
|
15 |
#' report_null(NULL) |
|
16 |
setGeneric("report_null", function(tlg, ...) { |
|
17 | 266x |
standardGeneric("report_null") |
18 |
}) |
|
19 | ||
20 |
#' @rdname report_null |
|
21 |
setMethod("report_null", "NULL", function(tlg, ind = 2L, ...) { |
|
22 | 1x |
res <- null_report |
23 | 1x |
table_inset(res) <- ind |
24 | 1x |
res |
25 |
}) |
|
26 | ||
27 |
#' @rdname report_null |
|
28 |
setMethod("report_null", "VTableTree", function(tlg, ind = 2L, ...) { |
|
29 | 219x |
res <- if (nrow(tlg) == 0L || count_children(tlg) == 0) { |
30 | 29x |
null_report |
31 |
} else { |
|
32 | 190x |
tlg |
33 |
} |
|
34 | ||
35 | 219x |
table_inset(res) <- ind |
36 | 219x |
res |
37 |
}) |
|
38 | ||
39 |
#' @rdname report_null |
|
40 |
setMethod("report_null", "listing_df", function(tlg, ind = 2L, ...) { |
|
41 | 10x |
if (nrow(tlg) == 0L) { |
42 | 2x |
res <- null_report |
43 | 2x |
table_inset(res) <- ind |
44 | 2x |
res |
45 |
} else { |
|
46 | 8x |
tlg |
47 |
} |
|
48 |
}) |
|
49 | ||
50 |
#' @rdname report_null |
|
51 |
setMethod("report_null", "list", function(tlg, ind = 2L, ...) { |
|
52 | 18x |
if (length(tlg) == 0) { |
53 | 1x |
res <- null_report |
54 | 1x |
table_inset(res) <- ind |
55 | 1x |
res |
56 |
} else { |
|
57 | 17x |
tlg |
58 |
} |
|
59 |
}) |
|
60 | ||
61 |
#' @rdname report_null |
|
62 |
setMethod("report_null", "ANY", function(tlg, ...) { |
|
63 | 18x |
tlg |
64 |
}) |
|
65 | ||
66 |
#' @export |
|
67 |
#' @rdname report_null |
|
68 |
null_report <- rtables::rtable( |
|
69 |
header = "", |
|
70 |
rrow("", "Null Report: No observations met the reporting criteria for inclusion in this output."), |
|
71 |
inset = 2L |
|
72 |
) |
|
73 | ||
74 |
#' Standard Post Processing |
|
75 |
#' |
|
76 |
#' @param tlg to post process. |
|
77 |
#' @param ... additional arguments passed to [report_null]. |
|
78 |
#' |
|
79 |
#' @returns a processed `tlg` or a null report. |
|
80 |
#' @export |
|
81 |
#' @examples |
|
82 |
#' library(rtables) |
|
83 |
#' std_postprocessing(build_table(basic_table() |> analyze("Species"), iris), ind = 10L) |
|
84 |
#' |
|
85 |
std_postprocessing <- function(tlg, ...) { |
|
86 | 218x |
tlg <- report_null(tlg, ...) |
87 | 218x |
tlg |
88 |
} |
1 |
# ttet01 ---- |
|
2 | ||
3 |
#' @describeIn ttet01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param dataset (`string`) the name of a table in the `adam_db` object. |
|
7 |
#' @param ref_group (`string`) The name of the reference group, the value should |
|
8 |
#' be identical to the values in `arm_var`, if not specified, it will by default |
|
9 |
#' use the first level or value of `arm_var`. |
|
10 |
#' @param summarize_event (`flag`) should the event description be displayed, default is TRUE |
|
11 |
#' @param perform_analysis (`string`) option to display statistical comparisons using stratified analyses, |
|
12 |
#' or unstratified analyses, or both, e.g. `c("unstrat", "strat")`. Only unstratified will be displayed by default |
|
13 |
#' @param strata (`string`) stratification factors, e.g. `strata = c("STRATA1", "STRATA2")`, by default as NULL |
|
14 |
#' @param ... Further arguments passed to `control_surv_time()`, `control_coxph()`, `control_survtp()`, and |
|
15 |
#' `surv_timepoint()`. For details, see the documentation in `tern`. Commonly used arguments include `pval_method`, |
|
16 |
#' `conf_level`, `conf_type`, `quantiles`, `ties`, `time_point`, `method`, etc. |
|
17 |
#' @returns the main function returns an `rtables` object. |
|
18 |
#' |
|
19 |
#' @details |
|
20 |
#' * No overall value. |
|
21 |
#' |
|
22 |
#' @export |
|
23 |
#' |
|
24 |
ttet01_main <- function(adam_db, |
|
25 |
dataset = "adtte", |
|
26 |
arm_var = "ARM", |
|
27 |
ref_group = NULL, |
|
28 |
summarize_event = TRUE, |
|
29 |
perform_analysis = "unstrat", |
|
30 |
strata = NULL, |
|
31 |
...) { |
|
32 | 1x |
assert_string(dataset) |
33 | 1x |
assert_all_tablenames(adam_db, "adsl", dataset) |
34 | 1x |
assert_string(arm_var) |
35 | 1x |
assert_string(ref_group, null.ok = TRUE) |
36 | 1x |
assert_flag(summarize_event) |
37 | 1x |
assert_subset(perform_analysis, c("unstrat", "strat")) |
38 | 1x |
assert_character( |
39 | 1x |
strata, |
40 | 1x |
null.ok = !"strat" %in% perform_analysis, |
41 | 1x |
min.len = as.integer(!"strat" %in% perform_analysis) |
42 |
) |
|
43 | 1x |
anl <- adam_db[[dataset]] |
44 | 1x |
assert_single_value(anl$PARAMCD, label = sprintf("adam_db$%s$PARAMCD", dataset)) |
45 | 1x |
df_label <- sprintf("adam_db$%s", dataset) |
46 | 1x |
assert_valid_variable(adam_db[[dataset]], c("IS_EVENT", "IS_NOT_EVENT"), types = list("logical"), label = df_label) |
47 | 1x |
assert_valid_variable(adam_db[[dataset]], "AVAL", types = list("numeric"), lower = 0, label = df_label) |
48 | 1x |
assert_valid_variable( |
49 | 1x |
adam_db[[dataset]], c("USUBJID", strata, arm_var, "EVNT1", "EVNTDESC", "AVALU"), |
50 | 1x |
types = list(c("character", "factor")), label = df_label |
51 |
) |
|
52 | 1x |
assert_subset(ref_group, lvls(adam_db[[dataset]][[arm_var]])) |
53 | 1x |
ref_group <- ref_group %||% lvls(anl[[arm_var]])[1] |
54 | 1x |
assert_single_value(anl$AVALU, label = sprintf("adam_db$%s$AVALU", dataset)) |
55 | ||
56 | 1x |
timeunit <- unique(anl[["AVALU"]]) |
57 | 1x |
event_lvls <- lvls(anl$EVNT1) |
58 | ||
59 | 1x |
control_survt <- execute_with_args(control_surv_time, ...) |
60 | 1x |
control_cox_ph <- execute_with_args(control_coxph, ...) |
61 | 1x |
control_survtp <- execute_with_args(control_surv_timepoint, ...) |
62 | ||
63 | 1x |
lyt <- ttet01_lyt( |
64 | 1x |
arm_var = arm_var, |
65 | 1x |
ref_group = ref_group, |
66 | 1x |
summarize_event = summarize_event, |
67 | 1x |
perform_analysis = perform_analysis, |
68 | 1x |
strata = strata, |
69 | 1x |
timeunit = timeunit, |
70 | 1x |
event_lvls = event_lvls, |
71 | 1x |
control_survt = control_survt, |
72 | 1x |
control_cox_ph = control_cox_ph, |
73 | 1x |
control_survtp = control_survtp, |
74 |
... |
|
75 |
) |
|
76 | ||
77 | 1x |
tbl <- build_table(lyt, anl) |
78 | ||
79 | 1x |
tbl |
80 |
} |
|
81 | ||
82 |
#' `ttet01` Layout |
|
83 |
#' |
|
84 |
#' @inheritParams gen_args |
|
85 |
#' @param timeunit (`string`) time unit get from `AVALU`, by default is `"Months"` |
|
86 |
#' |
|
87 |
#' @keywords internal |
|
88 |
#' |
|
89 |
ttet01_lyt <- function(arm_var, |
|
90 |
ref_group, |
|
91 |
summarize_event, |
|
92 |
perform_analysis, |
|
93 |
strata, |
|
94 |
timeunit, |
|
95 |
event_lvls, |
|
96 |
control_survt, |
|
97 |
control_cox_ph, |
|
98 |
control_survtp, |
|
99 |
...) { |
|
100 | 7x |
lyt01 <- basic_table(show_colcounts = TRUE) %>% |
101 | 7x |
split_cols_by( |
102 | 7x |
var = arm_var, ref_group = ref_group |
103 |
) %>% |
|
104 | 7x |
analyze_vars( |
105 | 7x |
vars = "IS_EVENT", |
106 | 7x |
.stats = "count_fraction", |
107 | 7x |
.labels = c(count_fraction = event_lvls[1]) |
108 |
) |
|
109 | ||
110 | 7x |
if (summarize_event) { |
111 | 4x |
lyt01 <- lyt01 %>% |
112 | 4x |
split_rows_by( |
113 | 4x |
"EVNT1", |
114 | 4x |
split_label = "Earliest contributing event", |
115 | 4x |
split_fun = keep_split_levels(event_lvls[1]), |
116 | 4x |
label_pos = "visible", |
117 | 4x |
child_labels = "hidden", |
118 | 4x |
indent_mod = 1L, |
119 |
) %>% |
|
120 | 4x |
analyze_vars("EVNTDESC", split_fun = drop_split_levels, .stats = "count") |
121 |
} |
|
122 | ||
123 | 7x |
lyt01 <- lyt01 %>% |
124 | 7x |
analyze_vars( |
125 | 7x |
vars = "IS_NOT_EVENT", |
126 | 7x |
.stats = "count_fraction", |
127 | 7x |
.labels = c(count_fraction = event_lvls[2]), |
128 | 7x |
nested = FALSE, |
129 | 7x |
show_labels = "hidden" |
130 |
) %>% |
|
131 | 7x |
surv_time( |
132 | 7x |
vars = "AVAL", |
133 | 7x |
var_labels = paste0("Time to Event (", timeunit, ")"), |
134 | 7x |
is_event = "IS_EVENT", |
135 | 7x |
control = control_survt, |
136 | 7x |
table_names = "time_to_event" |
137 |
) |
|
138 | ||
139 | 7x |
for (perform in perform_analysis) { |
140 | 9x |
lyt01 <- lyt01 %>% |
141 | 9x |
coxph_pairwise( |
142 | 9x |
vars = "AVAL", |
143 | 9x |
is_event = "IS_EVENT", |
144 | 9x |
var_labels = if (perform == "strat") "Stratified Analysis" else "Unstratified Analysis", |
145 | 9x |
strata = if (perform == "strat") strata else NULL, |
146 | 9x |
control = control_cox_ph, |
147 | 9x |
table_names = if (perform == "strat") "coxph_stratified" else "coxph_unstratified" |
148 |
) |
|
149 |
} |
|
150 | ||
151 | 7x |
lyt <- execute_with_args( |
152 | 7x |
surv_timepoint, |
153 | 7x |
lyt = lyt01, |
154 | 7x |
is_event = "IS_EVENT", |
155 | 7x |
vars = "AVAL", |
156 | 7x |
var_labels = timeunit, |
157 | 7x |
control = control_survtp, |
158 |
..., |
|
159 | 7x |
method = "both", |
160 | 7x |
time_point = c(6, 12), |
161 | 7x |
.labels = c("pt_at_risk" = render_safe("{Patient_label} remaining at risk")) |
162 |
) |
|
163 | ||
164 | 7x |
lyt |
165 |
} |
|
166 | ||
167 |
#' @describeIn ttet01 Preprocessing |
|
168 |
#' |
|
169 |
#' @inheritParams gen_args |
|
170 |
#' @param dataset (`string`) the name of a table in the `adam_db` object. |
|
171 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
172 |
#' @export |
|
173 |
#' |
|
174 |
ttet01_pre <- function(adam_db, dataset = "adtte", |
|
175 |
...) { |
|
176 | 1x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
177 | 1x |
mutate( |
178 | 1x |
AVAL = convert_to_month(.data$AVAL, .data$AVALU), |
179 | 1x |
AVALU = "MONTHS", |
180 | 1x |
IS_EVENT = .data$CNSR == 0, |
181 | 1x |
IS_NOT_EVENT = .data$CNSR == 1, |
182 | 1x |
EVNT1 = factor( |
183 | 1x |
case_when( |
184 | 1x |
IS_EVENT == TRUE ~ render_safe("{Patient_label} with event (%)"), |
185 | 1x |
IS_EVENT == FALSE ~ render_safe("{Patient_label} without event (%)") |
186 |
), |
|
187 | 1x |
levels = render_safe(c("{Patient_label} with event (%)", "{Patient_label} without event (%)")) |
188 |
), |
|
189 | 1x |
EVNTDESC = factor(.data$EVNTDESC) |
190 |
) |
|
191 | ||
192 | 1x |
adam_db |
193 |
} |
|
194 | ||
195 |
#' @describeIn ttet01 Postprocessing |
|
196 |
#' |
|
197 |
#' @inheritParams gen_args |
|
198 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
199 |
#' @export |
|
200 |
#' |
|
201 |
ttet01_post <- function(tlg, prune_0 = TRUE, ...) { |
|
202 | ! |
if (prune_0) { |
203 | ! |
tlg <- smart_prune(tlg) |
204 |
} |
|
205 | ! |
std_postprocessing(tlg) |
206 |
} |
|
207 | ||
208 |
#' `TTET01` Binary Outcomes Summary. |
|
209 |
#' |
|
210 |
#' `TTET01` template may be used to summarize any binary outcome or response variable at |
|
211 |
#' a single time point. Typical application for oncology |
|
212 |
#' |
|
213 |
#' @include chevron_tlg-S4class.R |
|
214 |
#' @export |
|
215 |
#' |
|
216 |
#' @examples |
|
217 |
#' library(dplyr) |
|
218 |
#' library(dunlin) |
|
219 |
#' |
|
220 |
#' proc_data <- log_filter(syn_data, PARAMCD == "PFS", "adtte") |
|
221 |
#' run(ttet01, proc_data) |
|
222 |
#' |
|
223 |
#' run(ttet01, proc_data, |
|
224 |
#' summarize_event = FALSE, perform_analysis = c("unstrat", "strat"), |
|
225 |
#' strata = c("STRATA1", "STRATA2"), |
|
226 |
#' conf_type = "log-log", |
|
227 |
#' time_point = c(6, 12), |
|
228 |
#' method = "both" |
|
229 |
#' ) |
|
230 |
ttet01 <- chevron_t( |
|
231 |
main = ttet01_main, |
|
232 |
preprocess = ttet01_pre, |
|
233 |
postprocess = ttet01_post |
|
234 |
) |
1 |
# lbt05 ---- |
|
2 | ||
3 |
#' @describeIn lbt05 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @returns the main function returns an `rtables` object. |
|
7 |
#' |
|
8 |
#' @details |
|
9 |
#' * Does not remove rows with zero counts by default. |
|
10 |
#' * Lab test results with missing `AVAL` values are excluded. |
|
11 |
#' * Split columns by arm, typically `ACTARM`. |
|
12 |
#' |
|
13 |
#' @note |
|
14 |
#' * `adam_db` object must contain an `adlb` table with columns `"ONTRTFL"`, `"PARCAT2"`, `"PARAM"`, `"ANRIND"`, |
|
15 |
#' `"AVALCAT1"`, and column specified by `arm_var`. |
|
16 |
#' |
|
17 |
#' @export |
|
18 |
#' |
|
19 |
lbt05_main <- function(adam_db, |
|
20 |
arm_var = "ACTARM", |
|
21 |
lbl_overall = NULL, |
|
22 |
...) { |
|
23 | 1x |
assert_all_tablenames(adam_db, c("adsl", "adlb")) |
24 | 1x |
assert_string(arm_var) |
25 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
26 | 1x |
assert_valid_variable(adam_db$adlb, c("PARAM", "AVALCAT1", "ABN_DIR"), types = list(c("character", "factor"))) |
27 | 1x |
assert_valid_variable(adam_db$adlb, c("USUBJID"), types = list(c("character", "factor")), empty_ok = TRUE) |
28 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID"), types = list(c("character", "factor"))) |
29 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adlb, arm_var) |
30 | ||
31 | 1x |
lbl_overall <- render_safe(lbl_overall) |
32 | 1x |
lbl_anrind <- var_labels_for(adam_db$adlb, "ABN_DIR") |
33 | 1x |
lbl_param <- var_labels_for(adam_db$adlb, "PARAM") |
34 | ||
35 | 1x |
map <- expand.grid( |
36 | 1x |
PARAM = levels(adam_db$adlb$PARAM), |
37 | 1x |
ABN_DIR = c("Low", "High"), |
38 | 1x |
stringsAsFactors = FALSE |
39 |
) %>% |
|
40 | 1x |
arrange(.data$PARAM, desc(.data$ABN_DIR)) |
41 | ||
42 | 1x |
lyt <- lbt05_lyt( |
43 | 1x |
arm_var = arm_var, |
44 | 1x |
lbl_overall = lbl_overall, |
45 | 1x |
lbl_param = lbl_param, |
46 | 1x |
lbl_anrind = lbl_anrind, |
47 | 1x |
map = map |
48 |
) |
|
49 | ||
50 | 1x |
tbl <- build_table(lyt, adam_db$adlb, alt_counts_df = adam_db$adsl) |
51 | ||
52 | 1x |
tbl |
53 |
} |
|
54 | ||
55 |
#' `lbt05` Layout |
|
56 |
#' |
|
57 |
#' @inheritParams gen_args |
|
58 |
#' |
|
59 |
#' @param lbl_param (`string`) label of the `PARAM` variable. |
|
60 |
#' @param lbl_anrind (`string`) label of the `ANRIND` variable. |
|
61 |
#' @param map (`data.frame`) mapping of `PARAM`s to directions of abnormality. |
|
62 |
#' |
|
63 |
#' @keywords internal |
|
64 |
#' |
|
65 |
lbt05_lyt <- function(arm_var, |
|
66 |
lbl_overall, |
|
67 |
lbl_param, |
|
68 |
lbl_anrind, |
|
69 |
map) { |
|
70 | 4x |
basic_table(show_colcounts = TRUE) %>% |
71 | 4x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
72 | 4x |
split_rows_by( |
73 | 4x |
"PARAM", |
74 | 4x |
label_pos = "topleft", |
75 | 4x |
split_label = lbl_param |
76 |
) %>% |
|
77 | 4x |
summarize_num_patients(var = "USUBJID", .stats = "unique_count") %>% |
78 | 4x |
split_rows_by("ABN_DIR", split_fun = trim_levels_to_map(map)) %>% |
79 | 4x |
count_abnormal_by_marked( |
80 | 4x |
var = "AVALCAT1", |
81 | 4x |
variables = list(id = "USUBJID", param = "PARAM", direction = "ABN_DIR"), |
82 | 4x |
.formats = c("count_fraction" = format_count_fraction_fixed_dp) |
83 |
) %>% |
|
84 | 4x |
append_topleft(paste(" ", lbl_anrind)) |
85 |
} |
|
86 | ||
87 |
#' @describeIn lbt05 Preprocessing |
|
88 |
#' |
|
89 |
#' @inheritParams gen_args |
|
90 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
91 |
#' @export |
|
92 |
#' |
|
93 |
lbt05_pre <- function(adam_db, ...) { |
|
94 | 1x |
adam_db$adlb <- adam_db$adlb %>% |
95 | 1x |
filter( |
96 | 1x |
.data$ONTRTFL == "Y", |
97 | 1x |
.data$PARCAT2 == "LS", |
98 | 1x |
!is.na(.data$AVAL) |
99 |
) %>% |
|
100 | 1x |
mutate(ABN_DIR = factor(case_when( |
101 | 1x |
ANRIND == "LOW LOW" ~ "Low", |
102 | 1x |
ANRIND == "HIGH HIGH" ~ "High", |
103 | 1x |
TRUE ~ "" |
104 | 1x |
), levels = c("Low", "High"))) %>% |
105 | 1x |
mutate( |
106 | 1x |
ABN_DIR = with_label(.data$ABN_DIR, "Direction of Abnormality"), |
107 | 1x |
PARAM = with_label(.data$PARAM, "Laboratory Test") |
108 |
) %>% |
|
109 | 1x |
mutate( |
110 | 1x |
across(all_of(c("AVALCAT1", "ABN_DIR")), ~ reformat(.x, missing_rule, .drop = FALSE)) |
111 |
) |
|
112 | ||
113 | 1x |
adam_db |
114 |
} |
|
115 | ||
116 |
#' @describeIn lbt05 Postprocessing |
|
117 |
#' |
|
118 |
#' @inheritParams gen_args |
|
119 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
120 |
#' @export |
|
121 |
#' |
|
122 |
lbt05_post <- function(tlg, prune_0 = FALSE, ...) { |
|
123 | 2x |
if (prune_0) { |
124 | 1x |
has_lbl <- function(lbl) CombinationFunction(function(tr) obj_label(tr) == lbl) |
125 | 1x |
tlg <- prune_table(tlg, keep_rows(has_lbl("Any Abnormality"))) |
126 | ||
127 | 1x |
if (is.null(prune_table(tlg))) { |
128 | ! |
tlg <- build_table(rtables::basic_table(), df = data.frame()) |
129 | ! |
col_info(tlg) <- col_info(tlg) |
130 |
} |
|
131 |
} |
|
132 | ||
133 | 2x |
std_postprocessing(tlg) |
134 |
} |
|
135 | ||
136 |
#' `LBT05` Table 1 (Default) Laboratory Abnormalities with Single and Replicated Marked. |
|
137 |
#' |
|
138 |
#' @include chevron_tlg-S4class.R |
|
139 |
#' @export |
|
140 |
#' |
|
141 |
#' @examples |
|
142 |
#' run(lbt05, syn_data) |
|
143 |
lbt05 <- chevron_t( |
|
144 |
main = lbt05_main, |
|
145 |
preprocess = lbt05_pre, |
|
146 |
postprocess = lbt05_post |
|
147 |
) |
1 |
# dmt01 ---- |
|
2 | ||
3 |
#' @describeIn dmt01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param summaryvars (`character`) variables summarized in demographic table. The label attribute of the corresponding |
|
7 |
#' column in `adsl` table of `adam_db` is used as label. |
|
8 |
#' @param stats (named `list` of character) where names of columns found in `.df_row` and the values indicate the |
|
9 |
#' statistical analysis to perform. If `default` is set, and parameter precision not specified, the |
|
10 |
#' value for `default` will be used. |
|
11 |
#' @param precision (named `list` of `integer`) where names are `strings` found in `summaryvars` and the values indicate |
|
12 |
#' the number of digits in statistics for numeric variables. If `default` is set, and parameter precision not |
|
13 |
#' specified, the value for `default` will be used. If neither are provided, auto determination is used. See |
|
14 |
#' [`tern::format_auto`]. |
|
15 |
#' @returns the main function returns an `rtables` object. |
|
16 |
#' |
|
17 |
#' @details |
|
18 |
#' * Information from `ADSUB` are generally included into `ADSL` before analysis. |
|
19 |
#' * Default demographic and characteristics table |
|
20 |
#' * If not specified otherwise, numbers represent absolute numbers of patients and fraction of `N` |
|
21 |
#' * Remove zero-count rows |
|
22 |
#' * Split columns by arm (planned or actual / code or description) |
|
23 |
#' * Include a total column by default |
|
24 |
#' |
|
25 |
#' @note |
|
26 |
#' * `adam_db` object must contain an `adsl` table with the columns specified in `summaryvars`. |
|
27 |
#' |
|
28 |
#' @export |
|
29 |
#' |
|
30 |
dmt01_main <- function(adam_db, |
|
31 |
arm_var = "ARM", |
|
32 |
lbl_overall = "All {Patient_label}", |
|
33 |
summaryvars = c( |
|
34 |
"AAGE", |
|
35 |
"AGEGR1", |
|
36 |
"SEX", |
|
37 |
"ETHNIC", |
|
38 |
"RACE" |
|
39 |
), |
|
40 |
stats = list(default = c("n", "mean_sd", "median", "range", "count_fraction")), |
|
41 |
precision = list(), |
|
42 |
...) { |
|
43 | 1x |
assert_string(arm_var) |
44 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
45 | 1x |
assert_character(summaryvars, null.ok = TRUE) |
46 | 1x |
assert_valid_variable(adam_db$adsl, summaryvars, na_ok = TRUE) |
47 | 1x |
assert_valid_variable(adam_db$adsl, summaryvars, types = list(c("numeric", "factor", "logical"))) |
48 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
49 | 1x |
assert_list(stats, types = "character") |
50 | 1x |
assert_list(precision, types = "integerish", names = "unique") |
51 | ||
52 | 1x |
lbl_overall <- render_safe(lbl_overall) |
53 | 1x |
summaryvars_lbls <- var_labels_for(adam_db$adsl, summaryvars) |
54 | ||
55 | 1x |
lyt <- dmt01_lyt( |
56 | 1x |
arm_var = arm_var, |
57 | 1x |
lbl_overall = lbl_overall, |
58 | 1x |
summaryvars = summaryvars, |
59 | 1x |
summaryvars_lbls = summaryvars_lbls, |
60 | 1x |
stats = stats, |
61 | 1x |
precision = precision |
62 |
) |
|
63 | ||
64 | 1x |
tbl <- build_table(lyt, adam_db$adsl) |
65 | ||
66 | 1x |
tbl |
67 |
} |
|
68 | ||
69 |
#' `dmt01` Layout |
|
70 |
#' @param summaryvars_lbls (`character`) labels corresponding to the analyzed variables. |
|
71 |
#' |
|
72 |
#' @inheritParams gen_args |
|
73 |
#' @returns a `PreDataTableLayouts` object. |
|
74 |
#' @keywords internal |
|
75 |
#' |
|
76 |
dmt01_lyt <- function(arm_var, |
|
77 |
lbl_overall, |
|
78 |
summaryvars, |
|
79 |
summaryvars_lbls, |
|
80 |
stats, |
|
81 |
precision) { |
|
82 | 11x |
basic_table(show_colcounts = TRUE) %>% |
83 | 11x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
84 | 11x |
analyze( |
85 | 11x |
vars = summaryvars, |
86 | 11x |
var_labels = summaryvars_lbls, |
87 | 11x |
afun = afun_p, |
88 | 11x |
extra_args = list( |
89 | 11x |
precision = precision, |
90 | 11x |
.stats = stats |
91 |
), |
|
92 | 11x |
show_labels = "visible" |
93 |
) |
|
94 |
} |
|
95 | ||
96 |
#' @describeIn dmt01 Preprocessing |
|
97 |
#' |
|
98 |
#' @inheritParams gen_args |
|
99 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
100 |
#' @export |
|
101 |
#' |
|
102 |
dmt01_pre <- function(adam_db, ...) { |
|
103 | 1x |
adam_db$adsl <- adam_db$adsl %>% |
104 | 1x |
mutate(SEX = reformat(.data$SEX, rule(Male = "M", Female = "F"))) |
105 | 1x |
adam_db |
106 |
} |
|
107 | ||
108 |
#' @describeIn dmt01 Postprocessing |
|
109 |
#' |
|
110 |
#' @inheritParams gen_args |
|
111 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
112 |
#' @export |
|
113 |
#' |
|
114 |
dmt01_post <- function(tlg, prune_0 = TRUE, ...) { |
|
115 | 1x |
if (prune_0) { |
116 | 1x |
tlg <- smart_prune(tlg) |
117 |
} |
|
118 | 1x |
std_postprocessing(tlg) |
119 |
} |
|
120 | ||
121 |
#' `DMT01` Table 1 (Default) Demographics and Baseline Characteristics Table 1. |
|
122 |
#' |
|
123 |
#' For each variable, summary statistics are |
|
124 |
#' by default based on the number of patients in the corresponding `n` row. |
|
125 |
#' |
|
126 |
#' @include chevron_tlg-S4class.R |
|
127 |
#' @export |
|
128 |
#' |
|
129 |
#' @examples |
|
130 |
#' run(dmt01, syn_data) |
|
131 |
dmt01 <- chevron_t( |
|
132 |
main = dmt01_main, |
|
133 |
preprocess = dmt01_pre, |
|
134 |
postprocess = dmt01_post |
|
135 |
) |
1 |
# egt05_qtcat ---- |
|
2 | ||
3 |
#' @describeIn egt05_qtcat Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param summaryvars (`character`) variables to be analyzed. The label attribute of the corresponding column in `adeg` |
|
7 |
#' table of `adam_db` is used as name. |
|
8 |
#' @returns the main function returns an `rtables` object. |
|
9 |
#' |
|
10 |
#' @details |
|
11 |
#' * The `Value at Visit` column, displays the categories of the specific `"PARAMCD"` value for patients. |
|
12 |
#' * The `Change from Baseline` column, displays the categories of the specific `"PARAMCD"` value |
|
13 |
#' change from baseline for patients. |
|
14 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
15 |
#' * Split columns by arm, typically `"ACTARM"`. |
|
16 |
#' * Does not include a total column by default. |
|
17 |
#' * Sorted based on factor level; by chronological time point given by `"AVISIT"` |
|
18 |
#' or user-defined visit incorporating `"ATPT"`. |
|
19 |
#' Re-level to customize order. |
|
20 |
#' * Please note that it is preferable to convert `summaryvars` to factor. |
|
21 |
#' |
|
22 |
#' @note |
|
23 |
#' * `adam_db` object must contain an `adeg` table with column specified in `visitvar`. |
|
24 |
#' For `summaryvars`, please make sure `AVALCAT1` and `CHGCAT1` columns existed in input data sets. |
|
25 |
#' |
|
26 |
#' @export |
|
27 |
#' |
|
28 |
egt05_qtcat_main <- function(adam_db, |
|
29 |
arm_var = "ACTARM", |
|
30 |
lbl_overall = NULL, |
|
31 |
summaryvars = c("AVALCAT1", "CHGCAT1"), |
|
32 |
row_split_var = NULL, |
|
33 |
visitvar = "AVISIT", |
|
34 |
page_var = NULL, |
|
35 |
...) { |
|
36 | 1x |
assert_all_tablenames(adam_db, c("adsl", "adeg")) |
37 | 1x |
assert_string(arm_var) |
38 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
39 | 1x |
assert_character(summaryvars) |
40 | 1x |
assert_character(row_split_var, null.ok = TRUE) |
41 | 1x |
assert_string(visitvar) |
42 | 1x |
assert_string(page_var, null.ok = TRUE) |
43 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adeg, arm_var) |
44 | 1x |
assert_valid_variable(adam_db$adeg, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
45 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
46 | 1x |
assert_valid_variable(adam_db$adeg, c("PARAM", "PARAMCD"), types = list(c("character", "factor")), na_ok = FALSE) |
47 | 1x |
assert_valid_variable(adam_db$adeg, visitvar, types = list("character", "factor")) |
48 | 1x |
assert_disjunct(row_split_var, c("PARAMCD", "PARAM", visitvar)) |
49 | 1x |
assert_valid_variable(adam_db$adeg, summaryvars, types = list(c("factor", "character")), na_ok = TRUE) |
50 | 1x |
assert_subset(page_var, c(row_split_var, "PARAMCD")) |
51 | ||
52 | 1x |
lbl_overall <- render_safe(lbl_overall) |
53 | 1x |
lbl_avisit <- var_labels_for(adam_db$adeg, visitvar) |
54 | 1x |
lbl_param <- var_labels_for(adam_db$adeg, "PARAM") |
55 | 1x |
summaryvars_lbls <- var_labels_for(adam_db$adeg, summaryvars) # Value at visit / change from baseline |
56 | 1x |
row_split_lbl <- var_labels_for(adam_db$adeg, row_split_var) |
57 | ||
58 | 1x |
lyt <- egt05_qtcat_lyt( |
59 | 1x |
arm_var = arm_var, |
60 | 1x |
lbl_overall = lbl_overall, |
61 | 1x |
lbl_avisit = lbl_avisit, |
62 | 1x |
lbl_param = lbl_param, |
63 | 1x |
lbl_cat = "Category", |
64 | 1x |
summaryvars = summaryvars, |
65 | 1x |
summaryvars_lbls = summaryvars_lbls, |
66 | 1x |
row_split_var = row_split_var, |
67 | 1x |
row_split_lbl = row_split_lbl, |
68 | 1x |
visitvar = visitvar, |
69 | 1x |
page_var = page_var |
70 |
) |
|
71 | ||
72 | 1x |
build_table( |
73 | 1x |
lyt, |
74 | 1x |
df = adam_db$adeg, |
75 | 1x |
alt_counts_df = adam_db$adsl |
76 |
) |
|
77 |
} |
|
78 | ||
79 |
#' `EGT05_QTCAT` Layout |
|
80 |
#' |
|
81 |
#' @inheritParams gen_args |
|
82 |
#' |
|
83 |
#' @param lbl_avisit (`string`) label of the `visitvar` variable. |
|
84 |
#' @param lbl_param (`string`) label of the `PARAM` variable. |
|
85 |
#' @param lbl_cat (`string`) label of the Category of `summaryvars` variable. Default as `Category`. |
|
86 |
#' @param summaryvars (`character`) the variables to be analyzed. `AVALCAT1` and `CHGCAT1` by default. |
|
87 |
#' @param summaryvars_lbls (`character`) the label of the variables to be analyzed. |
|
88 |
#' @param visitvar (`string`) typically `"AVISIT"` or user-defined visit incorporating `"ATPT"`. |
|
89 |
#' @returns a `PreDataTableLayouts` object. |
|
90 |
#' |
|
91 |
#' @keywords internal |
|
92 |
#' |
|
93 |
egt05_qtcat_lyt <- function(arm_var, |
|
94 |
lbl_overall, |
|
95 |
lbl_avisit, |
|
96 |
lbl_param, |
|
97 |
lbl_cat, |
|
98 |
summaryvars, |
|
99 |
summaryvars_lbls, |
|
100 |
row_split_var, |
|
101 |
row_split_lbl, |
|
102 |
visitvar, |
|
103 |
page_var) { |
|
104 | 3x |
page_by <- get_page_by(page_var, c(row_split_var, "PARAMCD")) |
105 | 3x |
label_pos <- ifelse(page_by, "hidden", "topleft") |
106 | 3x |
basic_table(show_colcounts = TRUE) %>% |
107 | 3x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
108 | 3x |
split_rows_by_recursive( |
109 | 3x |
row_split_var, |
110 | 3x |
split_label = row_split_lbl, |
111 | 3x |
label_pos = head(label_pos, -1L), page_by = head(page_by, -1L) |
112 |
) %>% |
|
113 | 3x |
split_rows_by( |
114 | 3x |
var = "PARAMCD", |
115 | 3x |
labels_var = "PARAM", |
116 | 3x |
split_fun = drop_split_levels, |
117 | 3x |
label_pos = tail(label_pos, 1L), |
118 | 3x |
split_label = lbl_param, |
119 | 3x |
page_by = tail(page_by, 1L) |
120 |
) %>% |
|
121 | 3x |
split_rows_by( |
122 | 3x |
visitvar, |
123 | 3x |
split_fun = drop_split_levels, |
124 | 3x |
split_label = lbl_avisit, |
125 | 3x |
label_pos = "topleft" |
126 |
) %>% |
|
127 | 3x |
summarize_vars_allow_na( |
128 | 3x |
vars = summaryvars, |
129 | 3x |
var_labels = summaryvars_lbls, |
130 | 3x |
inclNAs = FALSE |
131 |
) %>% |
|
132 | 3x |
append_topleft(paste0(stringr::str_dup(" ", sum(!page_by) * 2 + 2), lbl_cat)) |
133 |
} |
|
134 | ||
135 |
#' @describeIn egt05_qtcat Preprocessing |
|
136 |
#' |
|
137 |
#' @inheritParams gen_args |
|
138 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
139 |
#' |
|
140 |
#' @export |
|
141 |
#' |
|
142 |
egt05_qtcat_pre <- function(adam_db, ...) { |
|
143 | 1x |
adam_db$adeg <- adam_db$adeg %>% |
144 | 1x |
filter(.data$ANL01FL == "Y") %>% |
145 | 1x |
mutate( |
146 | 1x |
AVALCAT1 = reformat(.data$AVALCAT1, empty_rule), |
147 | 1x |
CHGCAT1 = reformat(.data$CHGCAT1, empty_rule), |
148 | 1x |
AVISIT = reorder(.data$AVISIT, .data$AVISITN), |
149 | 1x |
AVISIT = with_label(.data$AVISIT, "Analysis Visit") |
150 |
) |
|
151 | 1x |
adam_db |
152 |
} |
|
153 | ||
154 |
#' @describeIn egt05_qtcat Postprocessing |
|
155 |
#' |
|
156 |
#' @inheritParams gen_args |
|
157 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
158 |
#' |
|
159 |
#' @export |
|
160 |
#' |
|
161 |
egt05_qtcat_post <- function(tlg, prune_0 = TRUE, ...) { |
|
162 | 1x |
if (prune_0) tlg <- smart_prune(tlg) |
163 | 1x |
std_postprocessing(tlg) |
164 |
} |
|
165 | ||
166 |
#' `EGT05_QTCAT` ECG Actual Values and Changes from Baseline by Visit Table. |
|
167 |
#' |
|
168 |
#' The `EGT05_QTCAT` table summarizes several electrocardiogram parameters and their evolution |
|
169 |
#' throughout the study. |
|
170 |
#' |
|
171 |
#' @include chevron_tlg-S4class.R |
|
172 |
#' @export |
|
173 |
#' |
|
174 |
#' @examples |
|
175 |
#' run(egt05_qtcat, syn_data) |
|
176 |
egt05_qtcat <- chevron_t( |
|
177 |
main = egt05_qtcat_main, |
|
178 |
preprocess = egt05_qtcat_pre, |
|
179 |
postprocess = egt05_qtcat_post |
|
180 |
) |
1 |
#' Check that all names are among column names |
|
2 |
#' |
|
3 |
#' @param df (`data.frame`) |
|
4 |
#' @param x (`character`) the names of the columns to be checked. |
|
5 |
#' @param null_ok (`flag`) can `x` be NULL. |
|
6 |
#' @param qualifier (`string`) to be returned if the check fails. |
|
7 |
#' @returns invisible `NULL` or a string if the criteria are not fulfilled. |
|
8 |
#' |
|
9 |
#' @keywords internal |
|
10 |
check_all_colnames <- function(df, x, null_ok = TRUE, qualifier = NULL) { |
|
11 | 2x |
assert_data_frame(df) |
12 | 2x |
assert_character(x, null.ok = null_ok) |
13 | 2x |
assert_string(qualifier, null.ok = TRUE) |
14 | ||
15 | 2x |
diff <- setdiff(x, colnames(df)) |
16 | ||
17 | 2x |
if (length(diff) == 0) { |
18 | 1x |
invisible(NULL) |
19 |
} else { |
|
20 | 1x |
paste(qualifier, "Expected column names:", toString(diff), "not in", deparse(substitute(df))) |
21 |
} |
|
22 |
} |
|
23 | ||
24 |
#' Check that at least one name is among column names |
|
25 |
#' |
|
26 |
#' @param df (`data.frame`) |
|
27 |
#' @param x (`character`) the names of the columns to be checked. |
|
28 |
#' @param null_ok (`flag`) can `x` be NULL. |
|
29 |
#' @param qualifier (`string`) to be returned if the check fails. |
|
30 |
#' @returns invisible `NULL` or a string if the criteria are not fulfilled. |
|
31 |
#' |
|
32 |
#' @keywords internal |
|
33 |
check_one_colnames <- function(df, x, null_ok = TRUE, qualifier = NULL) { |
|
34 | 2x |
assert_data_frame(df) |
35 | 2x |
assert_character(x, null.ok = null_ok) |
36 | 2x |
assert_string(qualifier, null.ok = TRUE) |
37 | ||
38 | 2x |
common <- intersect(x, colnames(df)) |
39 | ||
40 | 2x |
if (length(common) > 0) { |
41 | 1x |
invisible(NULL) |
42 |
} else { |
|
43 | 1x |
paste(qualifier, "At least one of:", toString(x), "is expected to be a column name of", deparse(substitute(df))) |
44 |
} |
|
45 |
} |
1 |
# coxt01 ---- |
|
2 | ||
3 |
#' @describeIn coxt01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param arm_var (`string`) the arm variable used for arm splitting. |
|
7 |
#' @param time_var (`string`) the time variable in a Cox proportional hazards regression model. |
|
8 |
#' @param event_var (`string`) the event variable in a Cox proportional hazards regression model. |
|
9 |
#' @param covariates (`character`) will be fitted and the corresponding effect will be estimated. |
|
10 |
#' @param strata (`character`) will be fitted for the stratified analysis. |
|
11 |
#' @param lbl_vars (`string`) text label for the a Cox regression model variables. |
|
12 |
#' @param multivar (`flag`) indicator of whether multivariate cox regression is conducted. |
|
13 |
#' @param ... Further arguments passed to `tern::control_coxreg()`. |
|
14 |
#' @returns the main function returns an `rtables` object |
|
15 |
#' |
|
16 |
#' @details |
|
17 |
#' * The reference arm will always the first level of `arm_var`. Please change the level if you want to |
|
18 |
#' change the reference arms. |
|
19 |
#' * The table allows confidence level to be adjusted, default is two-sided 95%. |
|
20 |
#' * The stratified analysis is with DISCRETE tie handling (equivalent to `tern::control_coxreg(ties = "exact")` in R). |
|
21 |
#' * Model includes treatment plus specified covariate(s) as factor(s) or numeric(s), |
|
22 |
#' with `"SEX"`, `"RACE"` and `"AAGE"` as default candidates. |
|
23 |
#' * The selection of the covariates and whether or not there is a selection process |
|
24 |
#' (vs. a fixed, pre-specified list) needs to be pre-specified. |
|
25 |
#' * For pairwise comparisons using the hazard ratio, the value for the control group is the denominator. |
|
26 |
#' * Keep zero-count rows unless overridden with `prune_0 = TRUE`. |
|
27 |
#' |
|
28 |
#' @note |
|
29 |
#' * `adam_db` object must contain an `adtte` table with `"PARAMCD"`, `"ARM"`, |
|
30 |
#' `"AVAL"`, `"CNSR`, and the columns specified by `"covariates"` which is denoted as |
|
31 |
#' `c("SEX", "RACE", "AAGE")` by default. |
|
32 |
#' |
|
33 |
#' @export |
|
34 |
#' |
|
35 |
coxt01_main <- function(adam_db, |
|
36 |
arm_var = "ARM", |
|
37 |
time_var = "AVAL", |
|
38 |
event_var = "EVENT", |
|
39 |
covariates = c("SEX", "RACE", "AAGE"), |
|
40 |
strata = NULL, |
|
41 |
lbl_vars = "Effect/Covariate Included in the Model", |
|
42 |
multivar = FALSE, |
|
43 |
...) { |
|
44 | 2x |
assert_all_tablenames(adam_db, "adtte") |
45 | 2x |
assert_string(arm_var) |
46 | 2x |
assert_string(time_var) |
47 | 2x |
assert_string(event_var) |
48 | 2x |
assert_character(covariates, null.ok = TRUE) |
49 | 2x |
assert_character(strata, null.ok = TRUE) |
50 | 2x |
assert_flag(multivar) |
51 | 2x |
assert_valid_variable(adam_db$adtte, arm_var, types = list("factor"), n.levels = if (!multivar) 2L) |
52 | 2x |
assert_valid_variable(adam_db$adtte, c("USUBJID", arm_var, "PARAMCD"), types = list(c("character", "factor"))) |
53 | 2x |
assert_valid_variable(adam_db$adtte, strata, types = list(c("factor", "integer", "character")), na_ok = TRUE) |
54 | 2x |
assert_valid_variable(adam_db$adtte, covariates, na_ok = TRUE) |
55 | 2x |
assert_valid_variable(adam_db$adtte, event_var, types = list("numeric"), integerish = TRUE, lower = 0L, upper = 1L) |
56 | 2x |
assert_valid_variable(adam_db$adtte, time_var, types = list("numeric"), lower = 0) |
57 | 2x |
assert_single_value(adam_db$adtte$PARAMCD) |
58 | 2x |
control <- execute_with_args(control_coxreg, ...) |
59 | ||
60 | 2x |
variables <- list( |
61 | 2x |
time = time_var, |
62 | 2x |
event = event_var, |
63 | 2x |
arm = arm_var, |
64 | 2x |
covariates = covariates, |
65 | 2x |
strata = strata |
66 |
) |
|
67 | ||
68 | 2x |
lyt <- coxt01_lyt( |
69 | 2x |
variables = variables, |
70 | 2x |
col_split = if (!multivar) "COL_LABEL", |
71 | 2x |
lbl_vars = lbl_vars, |
72 | 2x |
multivar = multivar, |
73 | 2x |
control = control, |
74 |
... |
|
75 |
) |
|
76 | ||
77 | 2x |
col_split <- "Treatment Effect Adjusted for Covariate" |
78 | 2x |
adam_db$adtte$COL_LABEL <- factor(rep(col_split, nrow(adam_db$adtte)), levels = col_split) |
79 | ||
80 | 2x |
tbl <- build_table(lyt, adam_db$adtte) |
81 | ||
82 | 2x |
tbl |
83 |
} |
|
84 | ||
85 |
#' `COXT01` Layout |
|
86 |
#' |
|
87 |
#' @inheritParams coxt01_main |
|
88 |
#' @param variables (`list`) list of variables in a Cox proportional hazards regression model. |
|
89 |
#' @returns a `PreDataTableLayouts` object. |
|
90 |
#' @keywords internal |
|
91 |
#' |
|
92 |
coxt01_lyt <- function(variables, |
|
93 |
col_split, |
|
94 |
lbl_vars, |
|
95 |
control, |
|
96 |
multivar, |
|
97 |
...) { |
|
98 | 10x |
lyt <- basic_table() %>% |
99 | 10x |
ifneeded_split_col(col_split) |
100 | 10x |
lyt <- execute_with_args( |
101 | 10x |
summarize_coxreg, |
102 | 10x |
lyt = lyt, variables = variables, control = control, multivar = multivar, ... |
103 |
) |
|
104 | 10x |
lyt %>% |
105 | 10x |
append_topleft(lbl_vars) |
106 |
} |
|
107 | ||
108 |
#' @describeIn coxt01 Preprocessing |
|
109 |
#' |
|
110 |
#' @inheritParams coxt01_main |
|
111 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
112 |
#' @export |
|
113 |
#' |
|
114 |
coxt01_pre <- function(adam_db, arm_var = "ARM", ...) { |
|
115 | 2x |
adam_db$adtte <- adam_db$adtte %>% |
116 | 2x |
mutate(EVENT = 1 - .data$CNSR) %>% |
117 | 2x |
mutate(!!arm_var := forcats::fct_drop(!!sym(arm_var))) |
118 | ||
119 | 2x |
adam_db |
120 |
} |
|
121 | ||
122 |
#' @describeIn coxt01 Postprocessing |
|
123 |
#' |
|
124 |
#' @inheritParams gen_args |
|
125 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
126 |
#' @export |
|
127 |
#' |
|
128 |
coxt01_post <- function(tlg, prune_0 = FALSE, ...) { |
|
129 | 2x |
if (prune_0) { |
130 | ! |
tlg <- smart_prune(tlg) |
131 |
} |
|
132 | 2x |
std_postprocessing(tlg) |
133 |
} |
|
134 | ||
135 |
#' `COXT01` (Default) Cox Regression Model Table. |
|
136 |
#' |
|
137 |
#' Cox models are the most commonly used methods to estimate the magnitude of the effect in survival analyses. |
|
138 |
#' It assumes proportional hazards; that is, it assumes that the ratio of the hazards |
|
139 |
#' of the two groups (e.g. two arms) is constant over time. |
|
140 |
#' This ratio is referred to as the "hazard ratio" and is one of the most commonly reported metrics |
|
141 |
#' to describe the effect size in survival analysis. |
|
142 |
#' |
|
143 |
#' @include chevron_tlg-S4class.R |
|
144 |
#' @export |
|
145 |
#' |
|
146 |
#' @examples |
|
147 |
#' library(dunlin) |
|
148 |
#' |
|
149 |
#' proc_data <- log_filter(syn_data, PARAMCD == "CRSD", "adtte") |
|
150 |
#' proc_data <- log_filter(proc_data, ARMCD != "ARM C", "adsl") |
|
151 |
#' run(coxt01, proc_data) |
|
152 |
#' |
|
153 |
#' run(coxt01, proc_data, covariates = c("SEX", "AAGE"), strata = c("RACE"), conf_level = 0.90) |
|
154 |
coxt01 <- chevron_t( |
|
155 |
main = coxt01_main, |
|
156 |
preprocess = coxt01_pre, |
|
157 |
postprocess = coxt01_post |
|
158 |
) |
1 |
# aet05 ---- |
|
2 | ||
3 |
#' @describeIn aet05 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param dataset (`string`) the name of a table in the `adam_db` object. |
|
7 |
#' @param arm_var (`string`) the arm variable used for arm splitting. |
|
8 |
#' @param ... Further arguments passed to `tern::control_incidence_rate()`. |
|
9 |
#' @returns the main function returns an `rtables` object. |
|
10 |
#' |
|
11 |
#' @details |
|
12 |
#' * Total patient-years at risk is the sum over all patients of the time intervals (in years). |
|
13 |
#' * Split columns by arm, typically `ACTARM`. |
|
14 |
#' * Split rows by parameter code. |
|
15 |
#' * `AVAL` is patient-years at risk. |
|
16 |
#' * `N_EVENTS` is the number of adverse events observed. |
|
17 |
#' * The table allows confidence level to be adjusted, default is 95%. |
|
18 |
#' * Keep zero count rows by default. |
|
19 |
#' |
|
20 |
#' @note |
|
21 |
#' * `adam_db` object must contain table named as `dataset` with the columns `"PARAMCD"`, `"PARAM"`, |
|
22 |
#' `"AVAL"`, and `"CNSR"`. |
|
23 |
#' |
|
24 |
#' @export |
|
25 |
#' |
|
26 |
aet05_main <- function(adam_db, |
|
27 |
dataset = "adsaftte", |
|
28 |
arm_var = "ACTARM", |
|
29 |
lbl_overall = NULL, |
|
30 |
...) { |
|
31 | 2x |
assert_string(dataset) |
32 | 2x |
assert_all_tablenames(adam_db, "adsl", dataset) |
33 | 2x |
assert_string(arm_var) |
34 | 2x |
assert_string(lbl_overall, null.ok = TRUE) |
35 | 2x |
df_lbl <- paste0("adam_db$", dataset) |
36 | 2x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
37 | 2x |
assert_valid_variable(adam_db[[dataset]], c("USUBJID", arm_var, "PARAMCD", "PARAM"), |
38 | 2x |
types = list(c("character", "factor")), label = df_lbl |
39 |
) |
|
40 | 2x |
assert_valid_variable(adam_db[[dataset]], "AVAL", types = list("numeric"), lower = 0, na_ok = TRUE, label = df_lbl) |
41 | 2x |
assert_valid_variable(adam_db[[dataset]], "N_EVENTS", |
42 | 2x |
types = list("numeric"), integerish = TRUE, lower = 0L, |
43 | 2x |
label = df_lbl |
44 |
) |
|
45 | 2x |
assert_valid_var_pair(adam_db$adsl, adam_db[[dataset]], arm_var) |
46 | ||
47 | 2x |
lbl_overall <- render_safe(lbl_overall) |
48 | 2x |
control <- execute_with_args(control_incidence_rate, ...) |
49 | ||
50 | 2x |
lyt <- aet05_lyt( |
51 | 2x |
arm_var = arm_var, |
52 | 2x |
lbl_overall = lbl_overall, |
53 | 2x |
param_label = "PARAM", |
54 | 2x |
vars = "AVAL", |
55 | 2x |
n_events = "N_EVENTS", |
56 | 2x |
control = control |
57 |
) |
|
58 | ||
59 | 2x |
tbl <- build_table(lyt, adam_db[[dataset]], alt_counts_df = adam_db$adsl) |
60 | ||
61 | 2x |
tbl |
62 |
} |
|
63 | ||
64 |
#' `aet05` Layout |
|
65 |
#' |
|
66 |
#' @inheritParams gen_args |
|
67 |
#' @param param_label (`string`) variable for parameter code. |
|
68 |
#' @param vars (`string`) variable for the primary analysis variable to be iterated over. |
|
69 |
#' @param n_events (`string`) variable to count the number of events observed. |
|
70 |
#' @param control (`list`) parameters for estimation details, specified by using the helper function |
|
71 |
#' control_incidence_rate(). |
|
72 |
#' @returns a `PreDataTableLayouts` object. |
|
73 |
#' |
|
74 |
#' @keywords internal |
|
75 |
#' |
|
76 |
aet05_lyt <- function(arm_var, |
|
77 |
lbl_overall, |
|
78 |
param_label, |
|
79 |
vars, |
|
80 |
n_events, |
|
81 |
control) { |
|
82 | 8x |
lyt <- basic_table(show_colcounts = TRUE) %>% |
83 | 8x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
84 | 8x |
split_rows_by(param_label, split_fun = drop_split_levels) %>% |
85 | 8x |
estimate_incidence_rate( |
86 | 8x |
vars = vars, |
87 | 8x |
n_events = n_events, |
88 | 8x |
control = control |
89 |
) |
|
90 |
} |
|
91 | ||
92 |
#' @describeIn aet05 Preprocessing |
|
93 |
#' |
|
94 |
#' @inheritParams gen_args |
|
95 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
96 |
#' @export |
|
97 |
#' |
|
98 |
aet05_pre <- function(adam_db, dataset = "adsaftte", ...) { |
|
99 | 1x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
100 | 1x |
filter(grepl("(AE|CQ|SMQ)TTE", .data$PARAMCD)) %>% |
101 | 1x |
mutate( |
102 | 1x |
N_EVENTS = as.integer(.data$CNSR == 0) |
103 |
) |
|
104 | ||
105 | 1x |
adam_db |
106 |
} |
|
107 | ||
108 |
#' @describeIn aet05 Postprocessing |
|
109 |
#' |
|
110 |
#' @inheritParams gen_args |
|
111 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
112 |
#' @export |
|
113 |
#' |
|
114 |
aet05_post <- function(tlg, prune_0 = FALSE, ...) { |
|
115 | 2x |
if (prune_0) { |
116 | ! |
tlg <- smart_prune(tlg) |
117 |
} |
|
118 | 2x |
std_postprocessing(tlg) |
119 |
} |
|
120 | ||
121 |
#' `AET05` Table 1 (Default) Adverse Event Rate Adjusted for Patient-Years at Risk - First Occurrence. |
|
122 |
#' |
|
123 |
#' The `AET05` table produces the standard adverse event rate adjusted for patient-years at risk summary |
|
124 |
#' considering first occurrence. |
|
125 |
#' |
|
126 |
#' @include chevron_tlg-S4class.R |
|
127 |
#' @export |
|
128 |
#' |
|
129 |
#' @examples |
|
130 |
#' library(dplyr) |
|
131 |
#' library(dunlin) |
|
132 |
#' |
|
133 |
#' proc_data <- log_filter(syn_data, PARAMCD == "AETTE1", "adsaftte") |
|
134 |
#' |
|
135 |
#' run(aet05, proc_data) |
|
136 |
#' |
|
137 |
#' run(aet05, proc_data, conf_level = 0.90, conf_type = "exact") |
|
138 |
aet05 <- chevron_t( |
|
139 |
main = aet05_main, |
|
140 |
preprocess = aet05_pre, |
|
141 |
postprocess = aet05_post |
|
142 |
) |
1 |
# mng01 ---- |
|
2 | ||
3 |
#' @describeIn mng01 Main TLG Function |
|
4 |
#' |
|
5 |
#' @details |
|
6 |
#' * No overall value. |
|
7 |
#' * Preprocessing filters for `ANL01FL` in the selected data set. |
|
8 |
#' |
|
9 |
#' @inheritParams gen_args |
|
10 |
#' @param dataset (`string`) the name of a table in the `adam_db` object. |
|
11 |
#' @param x_var (`string`) the name of a column in the `dataset` to represent on the x-axis. |
|
12 |
#' @param y_var (`string`) the name of the variable to be represented on the y-axis. |
|
13 |
#' @param y_name (`string`) the variable name for `y`. Used for plot's subtitle. |
|
14 |
#' @param y_unit (`string`) the name of the variable with the units of `y`. Used for plot's subtitle. if `NULL`, only |
|
15 |
#' `y_name` is displayed as subtitle. |
|
16 |
#' @param center_fun (`string`) the function to compute the estimate value. |
|
17 |
#' @param interval_fun (`string`) the function defining the crossbar range. If `NULL`, no crossbar is displayed. |
|
18 |
#' @param jitter (`numeric`) the width of spread for data points on the x-axis; a number from 0 (no `jitter`) to 1 (high |
|
19 |
#' `jitter`), with a default of 0.3 (slight `jitter`). |
|
20 |
#' @param line_col (`character`) describing the colors to use for the lines or a named `character` associating values of |
|
21 |
#' `arm_var` with color names. |
|
22 |
#' @param line_type (`character`) describing the line type to use for the lines or a named `character` associating |
|
23 |
#' values of `arm_var` with line types. |
|
24 |
#' @param ggtheme (`theme`) passed to [tern::g_lineplot()]. |
|
25 |
#' @param table (`character`) names of the statistics to be displayed in the table. If `NULL`, no table is displayed. |
|
26 |
#' @param ... passed to [tern::g_lineplot()]. |
|
27 |
#' @returns the main function returns a `list` of `ggplot` objects. |
|
28 |
#' |
|
29 |
#' @note |
|
30 |
#' * `adam_db` object must contain the table specified by `dataset` with the columns specified by `x_var`, `y_var`, |
|
31 |
#' `y_name`, `y_unit` and `arm_var`. |
|
32 |
#' |
|
33 |
#' @seealso [gg_theme_chevron()], [tern::g_lineplot()]. |
|
34 |
#' |
|
35 |
#' @returns a list of `ggplot` objects. |
|
36 |
#' |
|
37 |
#' @export |
|
38 |
#' |
|
39 |
mng01_main <- function(adam_db, |
|
40 |
dataset = "adlb", |
|
41 |
x_var = "AVISIT", |
|
42 |
y_var = "AVAL", |
|
43 |
y_name = "PARAM", |
|
44 |
y_unit = NULL, |
|
45 |
arm_var = "ACTARM", |
|
46 |
center_fun = "mean", |
|
47 |
interval_fun = "mean_ci", |
|
48 |
jitter = 0.3, |
|
49 |
line_col = nestcolor::color_palette(), |
|
50 |
line_type = NULL, |
|
51 |
ggtheme = gg_theme_chevron(), |
|
52 |
table = c("n", center_fun, interval_fun), |
|
53 |
...) { |
|
54 | 3x |
center_fun_choice <- c("mean", "median") |
55 | 3x |
interval_fun_choice <- c("mean_ci", "mean_sei", "mean_sdi", "median_ci", "quantiles", "range") |
56 | ||
57 | 3x |
assert_all_tablenames(adam_db, c(dataset, "adsl")) |
58 | 3x |
assert_character(x_var) |
59 | 3x |
assert_string(y_var) |
60 | 3x |
assert_string(y_name) |
61 | 3x |
assert_string(y_unit, null.ok = TRUE) |
62 | 3x |
assert_string(arm_var) |
63 | 3x |
assert_string(center_fun) |
64 | 3x |
assert_string(interval_fun, null.ok = TRUE) |
65 | 3x |
assert_names(center_fun, subset.of = center_fun_choice) |
66 | 3x |
assert_choice(interval_fun, interval_fun_choice, null.ok = TRUE) |
67 | 3x |
assert_number(jitter, lower = 0, upper = 1) |
68 | 3x |
assert_class(ggtheme, "theme") |
69 | 3x |
assert_character(line_col, null.ok = TRUE) |
70 | 3x |
assert_character(line_type, null.ok = TRUE) |
71 | 3x |
assert_valid_variable(adam_db[[dataset]], x_var) |
72 | 3x |
assert_valid_variable(adam_db[[dataset]], y_var, types = list(c("numeric"))) |
73 | 3x |
assert_valid_variable(adam_db[[dataset]], y_unit, types = list(c("character", "factor"))) |
74 | 3x |
assert_valid_variable(adam_db[[dataset]], arm_var, types = list(c("character", "factor")), na_ok = FALSE) |
75 | 3x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
76 | 3x |
assert_valid_variable(adam_db[[dataset]], "USUBJID", types = list(c("character", "factor")), empty_ok = TRUE) |
77 | 3x |
assert_valid_var_pair(adam_db$adsl, adam_db[[dataset]], arm_var) |
78 | 3x |
assert_subset(table, c("n", center_fun_choice, interval_fun_choice)) |
79 | ||
80 | 3x |
df <- adam_db[[dataset]] |
81 | ||
82 | 3x |
data_ls <- split(df, df$PARAM, drop = TRUE) |
83 | 3x |
x_var <- paste(x_var, collapse = "_") |
84 | ||
85 | 3x |
whiskers_fun <- if (is.null(interval_fun)) { |
86 | ! |
NULL |
87 |
} else { |
|
88 | 3x |
switch(interval_fun, |
89 | 3x |
"mean_ci" = c("mean_ci_lwr", "mean_ci_upr"), |
90 | ! |
"mean_sei" = c("mean_sei_lwr", "mean_sei_upr"), |
91 | ! |
"mean_sdi" = c("mean_sdi_lwr", "mean_sdi_upr"), |
92 | ! |
"median_ci" = c("median_ci_lwr", "median_ci_upr"), |
93 | ! |
"quantiles" = c("quantiles_0.25", "quantile_0.75"), |
94 | ! |
"range" = c("min", "max") |
95 |
) |
|
96 |
} |
|
97 | ||
98 | ||
99 | 3x |
y_unit <- if (is.null(y_unit)) NA else y_unit |
100 | 3x |
variables <- tern::control_lineplot_vars( |
101 | 3x |
x = x_var, |
102 | 3x |
y = y_var, |
103 | 3x |
group_var = arm_var, |
104 | 3x |
paramcd = y_name, |
105 | 3x |
y_unit = y_unit, |
106 | 3x |
subject_var = "USUBJID" |
107 |
) |
|
108 | ||
109 | ||
110 | 3x |
arm_lvl <- sort(unique(df[[arm_var]])) |
111 | ||
112 | 3x |
col <- if (!is.null(names(line_col))) { |
113 | 2x |
col_sel <- line_col[as.character(arm_lvl)] |
114 | ||
115 | 2x |
if (anyNA(col_sel)) { |
116 | 1x |
missing_col <- setdiff(arm_lvl, names(col_sel)) |
117 | 1x |
stop(paste("Missing color matching for", toString(missing_col))) |
118 |
} |
|
119 | ||
120 | 1x |
unname(col_sel) |
121 |
} else { |
|
122 | 1x |
line_col |
123 |
} |
|
124 | ||
125 | 2x |
line_type <- if (!is.null(names(line_type))) { |
126 | ! |
tp <- line_type[as.character(arm_lvl)] |
127 | ||
128 | ! |
if (anyNA(tp)) { |
129 | ! |
missing_tp <- setdiff(arm_lvl, names(tp)) |
130 | ! |
stop(paste("Missing line type matching for", toString(missing_tp))) |
131 |
} |
|
132 | ||
133 | ! |
unname(tp) |
134 |
} else { |
|
135 | 2x |
line_type |
136 |
} |
|
137 | ||
138 | ||
139 | ||
140 | ||
141 | 2x |
lapply( |
142 | 2x |
data_ls, |
143 | 2x |
tern::g_lineplot, |
144 | 2x |
alt_counts_df = adam_db[["adsl"]], |
145 | 2x |
variables = variables, |
146 | 2x |
mid = center_fun, |
147 | 2x |
interval = interval_fun, |
148 | 2x |
whiskers = whiskers_fun, |
149 | 2x |
position = ggplot2::position_dodge(width = jitter), |
150 | 2x |
title = NULL, |
151 | 2x |
table = table, |
152 | 2x |
ggtheme = ggtheme, |
153 | 2x |
col = col, |
154 | 2x |
linetype = line_type, |
155 | 2x |
subtitle_add_unit = !is.na(y_unit), |
156 |
... |
|
157 |
) |
|
158 |
} |
|
159 | ||
160 |
#' @describeIn mng01 Preprocessing |
|
161 |
#' |
|
162 |
#' @inheritParams mng01_main |
|
163 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
164 |
#' @export |
|
165 |
#' |
|
166 |
mng01_pre <- function(adam_db, dataset, x_var = "AVISIT", ...) { |
|
167 | 2x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
168 | 2x |
filter(.data$ANL01FL == "Y") %>% |
169 | 2x |
mutate( |
170 | 2x |
AVISIT = reorder(.data$AVISIT, .data$AVISITN), |
171 | 2x |
AVISIT = with_label(.data$AVISIT, "Visit") |
172 |
) |
|
173 | ||
174 | 2x |
if (length(x_var) == 1 && is.numeric(adam_db[[dataset]][[x_var]])) { |
175 | ! |
adam_db |
176 |
} else { |
|
177 | 2x |
dunlin::ls_unite(adam_db, dataset, cols = x_var, sep = "_") |
178 |
} |
|
179 |
} |
|
180 | ||
181 |
# `mng01` Pipeline ---- |
|
182 | ||
183 |
#' `MNG01` Mean Plot Graph. |
|
184 |
#' |
|
185 |
#' Overview of a summary statistics across time and arm for a selected data set. |
|
186 |
#' |
|
187 |
#' @include chevron_tlg-S4class.R |
|
188 |
#' @export |
|
189 |
#' |
|
190 |
#' @examples |
|
191 |
#' col <- c( |
|
192 |
#' "A: Drug X" = "black", |
|
193 |
#' "B: Placebo" = "blue", |
|
194 |
#' "C: Combination" = "gray" |
|
195 |
#' ) |
|
196 |
#' |
|
197 |
#' lt <- c( |
|
198 |
#' "A: Drug X" = "29", |
|
199 |
#' "B: Placebo" = "99", |
|
200 |
#' "C: Combination" = "solid" |
|
201 |
#' ) |
|
202 |
#' |
|
203 |
#' run( |
|
204 |
#' mng01, |
|
205 |
#' syn_data, |
|
206 |
#' dataset = "adlb", |
|
207 |
#' x_var = c("AVISIT", "AVISITN"), |
|
208 |
#' line_col = col, |
|
209 |
#' line_type = lt |
|
210 |
#' ) |
|
211 |
mng01 <- chevron_g( |
|
212 |
main = mng01_main, |
|
213 |
preprocess = mng01_pre |
|
214 |
) |
1 |
# lbt06 ---- |
|
2 | ||
3 |
#' @describeIn lbt06 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param arm_var (`string`) the arm variable used for arm splitting. |
|
7 |
#' @returns the main function returns an `rtables` object. |
|
8 |
#' |
|
9 |
#' @details |
|
10 |
#' * Only count `"LOW"` or `"HIGH"` values for `ANRIND` and `BNRIND`. |
|
11 |
#' * Lab test results with missing `ANRIND` values are excluded. |
|
12 |
#' * Split columns by arm, typically `ACTARM`. |
|
13 |
#' * Keep zero count rows by default. |
|
14 |
#' |
|
15 |
#' @note |
|
16 |
#' * `adam_db` object must contain an `adlb` table with columns `"AVISIT"`, `"ANRIND"`, `"BNRIND"`, |
|
17 |
#' `"ONTRTFL"`, and `"PARCAT2"`, and column specified by `arm_var`. |
|
18 |
#' |
|
19 |
#' @export |
|
20 |
#' |
|
21 |
lbt06_main <- function(adam_db, |
|
22 |
arm_var = "ACTARM", |
|
23 |
lbl_overall = NULL, |
|
24 |
page_var = "PARAMCD", |
|
25 |
...) { |
|
26 | 2x |
assert_all_tablenames(adam_db, c("adsl", "adlb")) |
27 | 2x |
assert_string(arm_var) |
28 | 2x |
assert_string(lbl_overall, null.ok = TRUE) |
29 | 2x |
assert_subset(page_var, "PARAMCD") |
30 | 2x |
assert_valid_variable(adam_db$adlb, c(arm_var, "PARAMCD", "PARAM", "AVISIT"), types = list("characater", "factor")) |
31 | 2x |
assert_valid_variable(adam_db$adlb, c("ANRIND", "BNRIND"), types = list(c("character", "factor"))) |
32 | 2x |
assert_valid_variable(adam_db$adlb, c("USUBJID"), types = list(c("character", "factor"))) |
33 | 2x |
assert_valid_variable(adam_db$adsl, c("USUBJID"), types = list(c("character", "factor"))) |
34 | 2x |
assert_valid_var_pair(adam_db$adsl, adam_db$adlb, arm_var) |
35 | ||
36 | 2x |
lbl_overall <- render_safe(lbl_overall) |
37 | 2x |
lbl_param <- var_labels_for(adam_db$adlb, "PARAM") |
38 | 2x |
lbl_visit <- var_labels_for(adam_db$adlb, "AVISIT") |
39 | 2x |
lbl_anrind <- var_labels_for(adam_db$adlb, "ANRIND") |
40 | 2x |
lbl_bnrind <- var_labels_for(adam_db$adlb, "BNRIND") |
41 | ||
42 | 2x |
lyt <- lbt06_lyt( |
43 | 2x |
arm_var = arm_var, |
44 | 2x |
lbl_overall = lbl_overall, |
45 | 2x |
lbl_param = lbl_param, |
46 | 2x |
lbl_visit = lbl_visit, |
47 | 2x |
lbl_anrind = lbl_anrind, |
48 | 2x |
lbl_bnrind = lbl_bnrind, |
49 | 2x |
visitvar = "AVISIT", |
50 | 2x |
anrind_var = "ANRIND", |
51 | 2x |
bnrind_var = "BNRIND", |
52 | 2x |
page_var = page_var |
53 |
) |
|
54 | ||
55 | 2x |
tbl <- build_table(lyt, adam_db$adlb, alt_counts_df = adam_db$adsl) |
56 | ||
57 | 2x |
tbl |
58 |
} |
|
59 | ||
60 |
#' `lbt06` Layout |
|
61 |
#' |
|
62 |
#' @inheritParams gen_args |
|
63 |
#' |
|
64 |
#' @param lbl_param (`string`) text label of the `PARAM` variable. |
|
65 |
#' @param lbl_visit (`string`) text label of the `AVISIT` variable. |
|
66 |
#' @param lbl_anrind (`string`) text label of the `ANRIND` variable. |
|
67 |
#' @param lbl_bnrind (`string`) text label of the `BNRIND` variable. |
|
68 |
#' @param anrind_var (`string`) the variable for analysis reference range indicator. |
|
69 |
#' @param bnrind_var (`string`) the variable for baseline reference range indicator. |
|
70 |
#' |
|
71 |
#' @keywords internal |
|
72 |
#' |
|
73 |
lbt06_lyt <- function(arm_var, |
|
74 |
lbl_overall, |
|
75 |
lbl_param, |
|
76 |
lbl_visit, |
|
77 |
lbl_anrind, |
|
78 |
lbl_bnrind, |
|
79 |
visitvar, |
|
80 |
anrind_var, |
|
81 |
bnrind_var, |
|
82 |
page_var) { |
|
83 | 2x |
page_by <- !is.null(page_var) |
84 | 2x |
label_pos <- ifelse(page_by, "hidden", "topleft") |
85 | 2x |
basic_table(show_colcounts = TRUE) %>% |
86 | 2x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
87 | 2x |
split_rows_by( |
88 | 2x |
var = "PARAMCD", |
89 | 2x |
labels_var = "PARAM", |
90 | 2x |
split_fun = drop_split_levels, |
91 | 2x |
label_pos = label_pos, |
92 | 2x |
split_label = lbl_param, |
93 | 2x |
page_by = page_by |
94 |
) %>% |
|
95 | 2x |
split_rows_by( |
96 | 2x |
var = visitvar, |
97 | 2x |
split_fun = drop_split_levels, |
98 | 2x |
label_pos = "topleft", |
99 | 2x |
split_label = lbl_visit |
100 |
) %>% |
|
101 | 2x |
count_abnormal_by_baseline( |
102 | 2x |
var = anrind_var, |
103 | 2x |
abnormal = c(Low = "LOW", High = "HIGH"), |
104 | 2x |
variables = list(id = "USUBJID", baseline = bnrind_var), |
105 | 2x |
.indent_mods = 4L |
106 |
) %>% |
|
107 | 2x |
append_topleft(paste0(stringr::str_dup(" ", 2L * (2 - page_by)), lbl_anrind)) %>% |
108 | 2x |
append_topleft(paste0(stringr::str_dup(" ", 2L * (7 - page_by)), lbl_bnrind)) |
109 |
} |
|
110 | ||
111 |
#' @describeIn lbt06 Preprocessing |
|
112 |
#' |
|
113 |
#' @inheritParams gen_args |
|
114 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
115 |
#' @export |
|
116 |
#' |
|
117 |
lbt06_pre <- function(adam_db, ...) { |
|
118 | 3x |
adam_db$adlb <- adam_db$adlb %>% |
119 | 3x |
filter( |
120 | 3x |
.data$ONTRTFL == "Y", |
121 | 3x |
.data$PARCAT2 == "SI" |
122 |
) %>% |
|
123 | 3x |
mutate( |
124 | 3x |
across(all_of(c("ANRIND", "BNRIND")), ~ reformat(.x, missing_rule)), |
125 | 3x |
AVISIT = reorder(.data$AVISIT, .data$AVISITN), |
126 | 3x |
AVISIT = with_label(.data$AVISIT, "Visit"), |
127 | 3x |
ANRIND = with_label(.data$ANRIND, "Abnormality at Visit"), |
128 | 3x |
BNRIND = with_label(.data$BNRIND, "Baseline Status") |
129 |
) |
|
130 | ||
131 | 2x |
adam_db |
132 |
} |
|
133 | ||
134 |
#' @describeIn lbt06 Postprocessing |
|
135 |
#' |
|
136 |
#' @inheritParams gen_args |
|
137 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
138 |
#' @export |
|
139 |
#' |
|
140 |
lbt06_post <- function(tlg, prune_0 = FALSE, ...) { |
|
141 | 1x |
if (prune_0) { |
142 | 1x |
tlg <- smart_prune(tlg) |
143 |
} |
|
144 | 1x |
std_postprocessing(tlg) |
145 |
} |
|
146 | ||
147 |
#' `LBT06` Table 1 (Default) Laboratory Abnormalities by Visit and Baseline Status Table 1. |
|
148 |
#' |
|
149 |
#' The `LBT06` table produces the standard laboratory abnormalities by visit and |
|
150 |
#' baseline status summary. |
|
151 |
#' |
|
152 |
#' @include chevron_tlg-S4class.R |
|
153 |
#' @export |
|
154 |
#' |
|
155 |
#' @examples |
|
156 |
#' run(lbt06, syn_data) |
|
157 |
lbt06 <- chevron_t( |
|
158 |
main = lbt06_main, |
|
159 |
preprocess = lbt06_pre, |
|
160 |
postprocess = lbt06_post |
|
161 |
) |
1 |
# fstg01 ---- |
|
2 | ||
3 |
#' @describeIn fstg01 Main TLG Function |
|
4 |
#' |
|
5 |
#' @details |
|
6 |
#' * No overall value. |
|
7 |
#' * Keep zero count rows by default. |
|
8 |
#' |
|
9 |
#' @inheritParams gen_args |
|
10 |
#' @param dataset (`string`) the name of a table in the `adam_db` object. |
|
11 |
#' @param arm_var (`string`) the arm variable name used for group splitting. |
|
12 |
#' @param rsp_var (`string`) the response variable name to flag whether each subject is a binary response or not. |
|
13 |
#' @param subgroups (`character`) the subgroups variable name to list baseline risk factors. |
|
14 |
#' @param strata_var (`character`) required if stratified analysis is performed. |
|
15 |
#' @param stat_var (`character`) the names of statistics to be reported in `tabulate_rsp_subgroups`. |
|
16 |
#' @param ... Further arguments passed to `g_forest` and `extract_rsp_subgroups` (a wrapper for |
|
17 |
#' `h_odds_ratio_subgroups_df` and `h_proportion_subgroups_df`). For details, see the documentation in `tern`. |
|
18 |
#' Commonly used arguments include `col_symbol_size`, `col`, `vline`, `groups_lists`, `conf_level`, |
|
19 |
#' `method`, `label_all`, etc. |
|
20 |
#' @returns the main function returns a `grob` object. |
|
21 |
#' |
|
22 |
#' @note |
|
23 |
#' * `adam_db` object must contain the table specified by `dataset` with `"PARAMCD"`, `"ARM"`, |
|
24 |
#' `"AVALC"`, and the columns specified by `subgroups` which is denoted as |
|
25 |
#' `c("SEX", "AGEGR1", "RACE")` by default. |
|
26 |
#' * If the plot is too large to be rendered in the output, please provide `gp`, `width_row_names`, |
|
27 |
#' `width_columns` and `width_forest` manually to make it fit. See `tern::g_forest` for more details. |
|
28 |
#' |
|
29 |
#' @returns a `gTree` object. |
|
30 |
#' |
|
31 |
#' @export |
|
32 |
#' |
|
33 |
fstg01_main <- function(adam_db, |
|
34 |
dataset = "adrs", |
|
35 |
arm_var = "ARM", |
|
36 |
rsp_var = "IS_RSP", |
|
37 |
subgroups = c("SEX", "AGEGR1", "RACE"), |
|
38 |
strata_var = NULL, |
|
39 |
stat_var = c("n_tot", "n", "n_rsp", "prop", "or", "ci"), |
|
40 |
...) { |
|
41 | 1x |
assert_all_tablenames(adam_db, c("adsl", dataset)) |
42 | 1x |
df_lbl <- paste0("adam_db$", dataset) |
43 | 1x |
assert_string(arm_var) |
44 | 1x |
assert_string(rsp_var) |
45 | 1x |
assert_character(subgroups, null.ok = TRUE) |
46 | 1x |
assert_character(strata_var, null.ok = TRUE) |
47 | 1x |
assert_character(stat_var, null.ok = TRUE) |
48 | 1x |
assert_valid_variable(adam_db[[dataset]], arm_var, types = list("factor"), n.levels = 2, label = df_lbl) |
49 | 1x |
assert_valid_variable(adam_db[[dataset]], c("USUBJID", "PARAMCD"), |
50 | 1x |
types = list(c("character", "factor")), |
51 | 1x |
label = df_lbl |
52 |
) |
|
53 | 1x |
assert_valid_variable(adam_db[[dataset]], rsp_var, types = list("logical"), label = df_lbl) |
54 | 1x |
assert_valid_variable(adam_db[[dataset]], c(subgroups, strata_var), |
55 | 1x |
types = list(c("factor")), na_ok = TRUE, |
56 | 1x |
label = df_lbl |
57 |
) |
|
58 | 1x |
assert_single_value(adam_db[[dataset]]$PARAMCD, label = df_lbl) |
59 | ||
60 | 1x |
variables <- list( |
61 | 1x |
arm = arm_var, |
62 | 1x |
rsp = rsp_var, |
63 | 1x |
subgroups = subgroups, |
64 | 1x |
strata = strata_var |
65 |
) |
|
66 | ||
67 | 1x |
df <- execute_with_args(extract_rsp_subgroups, |
68 | 1x |
variables = variables, |
69 | 1x |
data = adam_db[[dataset]], |
70 |
... |
|
71 |
) |
|
72 | 1x |
result <- basic_table() %>% |
73 | 1x |
tabulate_rsp_subgroups(df, vars = stat_var) |
74 | 1x |
execute_with_args( |
75 | 1x |
g_forest, |
76 | 1x |
tbl = result, |
77 |
..., |
|
78 | 1x |
font_size = 7 |
79 |
) |
|
80 |
} |
|
81 | ||
82 |
#' @describeIn fstg01 Preprocessing |
|
83 |
#' |
|
84 |
#' @inheritParams fstg01_main |
|
85 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
86 |
#' |
|
87 |
#' @export |
|
88 |
#' |
|
89 |
fstg01_pre <- function(adam_db, ...) { |
|
90 | 1x |
adam_db$adrs <- adam_db$adrs %>% |
91 | 1x |
mutate( |
92 | 1x |
ARM = droplevels(.data$ARM), |
93 | 1x |
IS_RSP = .data$AVALC %in% c("CR", "PR") |
94 |
) |
|
95 | ||
96 | 1x |
adam_db |
97 |
} |
|
98 | ||
99 |
# `fstg01` Pipeline ---- |
|
100 | ||
101 |
#' `FSTG01` Subgroup Analysis of Best Overall Response. |
|
102 |
#' |
|
103 |
#' The template produces the subgroup analysis of best overall response graphic. |
|
104 |
#' |
|
105 |
#' @include chevron_tlg-S4class.R |
|
106 |
#' @export |
|
107 |
#' |
|
108 |
#' @examples |
|
109 |
#' library(dplyr) |
|
110 |
#' library(dunlin) |
|
111 |
#' |
|
112 |
#' proc_data <- log_filter( |
|
113 |
#' syn_data, |
|
114 |
#' PARAMCD == "BESRSPI" & ARM %in% c("A: Drug X", "B: Placebo"), "adrs" |
|
115 |
#' ) |
|
116 |
#' run(fstg01, proc_data, |
|
117 |
#' subgroups = c("SEX", "AGEGR1", "RACE"), |
|
118 |
#' conf_level = 0.90, dataset = "adrs" |
|
119 |
#' ) |
|
120 |
fstg01 <- chevron_g( |
|
121 |
main = fstg01_main, |
|
122 |
preprocess = fstg01_pre |
|
123 |
) |
1 |
# rmpt01 ---- |
|
2 | ||
3 |
#' @describeIn rmpt01 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param summaryvars (`string`) variables to be analyzed. The label attribute of the corresponding columns in `adex` |
|
7 |
#' table of `adam_db` is used as label. |
|
8 |
#' @param show_tot (`flag`) whether to display the cumulative total. |
|
9 |
#' @param row_split_var (`string`) the name of the column that containing variable to split exposure by. |
|
10 |
#' @param col_split_var (`string`) additional column splitting variable. |
|
11 |
#' @param overall_col_lbl (`string`) name of the overall column. If `NULL`, no overall level is added. |
|
12 |
#' @returns the main function returns an `rtables` object. |
|
13 |
#' |
|
14 |
#' @details |
|
15 |
#' * Person time is the sum of exposure across all patients. |
|
16 |
#' * Summary statistics are by default based on the number of patients in the corresponding `N` row |
|
17 |
#' (number of non-missing values). |
|
18 |
#' * Does not remove zero-count rows unless overridden with `prune_0 = TRUE`. |
|
19 |
#' |
|
20 |
#' @note |
|
21 |
#' * `adam_db` object must contain an `adex` table with `"AVAL"` and the columns specified by `summaryvars`. |
|
22 |
#' |
|
23 |
#' @export |
|
24 |
#' |
|
25 |
rmpt01_main <- function(adam_db, |
|
26 |
summaryvars = "AVALCAT1", |
|
27 |
show_tot = TRUE, |
|
28 |
row_split_var = NULL, |
|
29 |
col_split_var = NULL, |
|
30 |
overall_col_lbl = NULL, |
|
31 |
...) { |
|
32 | 4x |
assert_all_tablenames(adam_db, c("adsl", "adex")) |
33 | 4x |
assert_string(summaryvars) |
34 | 4x |
assert_flag(show_tot) |
35 | 4x |
assert_string(row_split_var, null.ok = TRUE) |
36 | 4x |
assert_string(col_split_var, null.ok = TRUE) |
37 | 4x |
assert_string(overall_col_lbl, null.ok = TRUE) |
38 | 4x |
assert_valid_variable(adam_db$adex, summaryvars, types = list(c("factor", "character")), empty_ok = TRUE) |
39 | 4x |
assert_valid_variable(adam_db$adex, "AVAL", types = list("numeric"), empty_ok = TRUE) |
40 | 4x |
assert_valid_variable(adam_db$adex, row_split_var, types = list(c("factor", "numeric")), empty_ok = TRUE) |
41 | 4x |
assert_valid_variable(adam_db$adex, col_split_var, types = list(c("factor", "character"))) |
42 | 4x |
assert_valid_variable(adam_db$adex, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
43 | 4x |
assert_valid_variable(adam_db$adsl, "USUBJID", types = list(c("character", "factor"))) |
44 | ||
45 | 4x |
lbl_summaryvars <- var_labels_for(adam_db$adex, summaryvars) |
46 | ||
47 | 4x |
lyt <- rmpt01_lyt( |
48 | 4x |
summaryvars = summaryvars, |
49 | 4x |
lbl_summaryvars = lbl_summaryvars, |
50 | 4x |
show_tot = show_tot, |
51 | 4x |
row_split_var = row_split_var, |
52 | 4x |
col_split_var = col_split_var, |
53 | 4x |
overall_col_lbl = overall_col_lbl |
54 |
) |
|
55 | ||
56 | 4x |
build_table(lyt, adam_db$adex, alt_counts_df = adam_db$adsl) |
57 |
} |
|
58 | ||
59 |
#' `rmpt01` Layout |
|
60 |
#' |
|
61 |
#' @inheritParams gen_args |
|
62 |
#' @inheritParams rmpt01_main |
|
63 |
#' @param lbl_summaryvars (`character`) label associated with the analyzed variables. |
|
64 |
#' |
|
65 |
#' @keywords internal |
|
66 |
#' |
|
67 |
rmpt01_lyt <- function(summaryvars, |
|
68 |
lbl_summaryvars, |
|
69 |
show_tot, |
|
70 |
row_split_var, |
|
71 |
col_split_var, |
|
72 |
overall_col_lbl) { |
|
73 | 21x |
lyt <- basic_table(show_colcounts = TRUE) %>% |
74 | 21x |
split_cols_by_with_overall(col_split_var, overall_col_lbl) %>% |
75 | 21x |
split_cols_by_multivar( |
76 | 21x |
vars = c("AVAL", "AVAL"), |
77 | 21x |
varlabels = c(n_patients = render_safe("{Patient_label}"), sum_exposure = "Person time"), |
78 | 21x |
extra_args = list(.stats = c("n_patients", "sum_exposure")) |
79 |
) %>% |
|
80 | 21x |
analyze_patients_exposure_in_cols( |
81 | 21x |
var = summaryvars, |
82 | 21x |
col_split = FALSE, |
83 | 21x |
add_total_level = show_tot, |
84 | 21x |
custom_label = render_safe("Total {patient_label} number/person time") |
85 |
) |
|
86 | ||
87 | 21x |
if (!is.null(row_split_var)) { |
88 | 4x |
lyt %>% |
89 | 4x |
split_rows_by(row_split_var) %>% |
90 | 4x |
analyze_patients_exposure_in_cols( |
91 | 4x |
.indent_mods = -1L, |
92 | 4x |
var = summaryvars, |
93 | 4x |
col_split = FALSE, |
94 | 4x |
add_total_level = show_tot, |
95 | 4x |
custom_label = render_safe("Total {patient_label} number/person time") |
96 |
) %>% |
|
97 | 4x |
append_topleft(c("", lbl_summaryvars)) |
98 |
} else { |
|
99 | 17x |
lyt %>% |
100 | 17x |
append_topleft(c("", lbl_summaryvars)) |
101 |
} |
|
102 |
} |
|
103 | ||
104 |
#' @describeIn rmpt01 Preprocessing |
|
105 |
#' |
|
106 |
#' @inheritParams gen_args |
|
107 |
#' @inheritParams rmpt01_main |
|
108 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
109 |
#' @export |
|
110 |
#' |
|
111 |
rmpt01_pre <- function(adam_db, |
|
112 |
summaryvars = "AVALCAT1", |
|
113 |
...) { |
|
114 | 4x |
adam_db$adex <- adam_db$adex %>% |
115 | 4x |
filter(.data$PARAMCD == "TDURD") |
116 | 4x |
adam_db$adex <- adam_db$adex %>% |
117 | 4x |
mutate(across(all_of(summaryvars), ~ reformat(.x, missing_rule))) %>% |
118 | 4x |
mutate( |
119 | 4x |
AVALCAT1 = with_label(.data$AVALCAT1, "Duration of exposure") |
120 |
) |
|
121 | 4x |
adam_db |
122 |
} |
|
123 | ||
124 |
#' @describeIn rmpt01 Postprocessing |
|
125 |
#' |
|
126 |
#' @inheritParams gen_args |
|
127 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
128 |
#' @export |
|
129 |
#' |
|
130 |
rmpt01_post <- function(tlg, prune_0 = FALSE, ...) { |
|
131 | 6x |
if (prune_0) { |
132 | ! |
tlg <- smart_prune(tlg) |
133 |
} |
|
134 | 6x |
std_postprocessing(tlg) |
135 |
} |
|
136 | ||
137 |
#' `RMPT01`Duration of Exposure for Risk Management Plan Table. |
|
138 |
#' |
|
139 |
#' The `RMPT01` table provides an overview of duration of exposure. |
|
140 |
#' |
|
141 |
#' @include chevron_tlg-S4class.R |
|
142 |
#' @export |
|
143 |
#' |
|
144 |
#' @examples |
|
145 |
#' run(rmpt01, syn_data, col_split_var = "SEX") |
|
146 |
rmpt01 <- chevron_t( |
|
147 |
main = rmpt01_main, |
|
148 |
preprocess = rmpt01_pre, |
|
149 |
postprocess = rmpt01_post |
|
150 |
) |
1 |
# aet10 ---- |
|
2 | ||
3 |
#' @describeIn aet10 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @returns the main function returns an `rtables` object |
|
7 |
#' @details |
|
8 |
#' * Numbers represent absolute numbers of subject and fraction of `N`, or absolute number of event when specified. |
|
9 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
10 |
#' * Split columns by arm. |
|
11 |
#' * Does not include a total column by default. |
|
12 |
#' * Sort Dictionary-Derived Code (`AEDECOD`) by highest overall frequencies. |
|
13 |
#' * Missing values in `AEDECOD` are labeled by `No Coding Available`. |
|
14 |
#' |
|
15 |
#' @note |
|
16 |
#' * `adam_db` object must contain an `adae` table with the columns `"AEDECOD"`. |
|
17 |
#' |
|
18 |
#' @export |
|
19 |
#' |
|
20 |
aet10_main <- function(adam_db, |
|
21 |
arm_var = "ACTARM", |
|
22 |
lbl_overall = NULL, |
|
23 |
...) { |
|
24 | 1x |
assert_all_tablenames(adam_db, "adsl", "adae") |
25 | 1x |
assert_string(arm_var) |
26 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
27 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
28 | 1x |
assert_valid_variable(adam_db$adae, c(arm_var, "AEBODSYS", "AEDECOD"), types = list(c("character", "factor"))) |
29 | 1x |
assert_valid_variable(adam_db$adae, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
30 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adae, arm_var) |
31 | ||
32 | 1x |
lbl_overall <- render_safe(lbl_overall) |
33 | 1x |
lbl_aedecod <- var_labels_for(adam_db$adae, "AEDECOD") |
34 | ||
35 | 1x |
lyt <- aet10_lyt( |
36 | 1x |
arm_var = arm_var, |
37 | 1x |
lbl_overall = lbl_overall, |
38 | 1x |
lbl_aedecod = lbl_aedecod |
39 |
) |
|
40 | ||
41 | 1x |
tbl <- build_table(lyt, adam_db$adae, alt_counts_df = adam_db$adsl) |
42 | ||
43 | 1x |
tbl |
44 |
} |
|
45 | ||
46 |
#' `aet10` Layout |
|
47 |
#' |
|
48 |
#' @inheritParams gen_args |
|
49 |
#' @param lbl_aedecod (`character`) text label for `AEDECOD`. |
|
50 |
#' @returns a `PreDataTableLayouts` object. |
|
51 |
#' @keywords internal |
|
52 |
#' |
|
53 |
aet10_lyt <- function(arm_var, |
|
54 |
lbl_overall, |
|
55 |
lbl_aedecod) { |
|
56 | 3x |
basic_table(show_colcounts = TRUE) %>% |
57 | 3x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
58 | 3x |
count_occurrences( |
59 | 3x |
vars = "AEDECOD", |
60 | 3x |
.indent_mods = -1L |
61 |
) %>% |
|
62 | 3x |
append_topleft(paste0("\n", lbl_aedecod)) |
63 |
} |
|
64 | ||
65 |
#' @describeIn aet10 Preprocessing |
|
66 |
#' |
|
67 |
#' @inheritParams gen_args |
|
68 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
69 |
#' @export |
|
70 |
#' |
|
71 |
aet10_pre <- function(adam_db, ...) { |
|
72 | 1x |
adam_db$adae <- adam_db$adae %>% |
73 | 1x |
filter(.data$ANL01FL == "Y") %>% |
74 | 1x |
mutate(AEDECOD = reformat(.data$AEDECOD, nocoding)) |
75 | 1x |
return(adam_db) |
76 |
} |
|
77 | ||
78 |
#' @describeIn aet10 Postprocessing |
|
79 |
#' |
|
80 |
#' @inheritParams gen_args |
|
81 |
#' @param atleast given cut-off in numeric format, default is `0.05` |
|
82 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
83 |
#' @export |
|
84 |
#' |
|
85 |
aet10_post <- function(tlg, atleast = 0.05, ...) { |
|
86 | 1x |
assert_number(atleast, lower = 0, upper = 1) |
87 | 1x |
tbl_sorted <- tlg %>% |
88 | 1x |
sort_at_path( |
89 | 1x |
path = c("AEDECOD"), |
90 | 1x |
scorefun = score_occurrences |
91 |
) |
|
92 | ||
93 | 1x |
tlg_prune <- prune_table( |
94 | 1x |
tt = tbl_sorted, |
95 | 1x |
prune_func = keep_rows( |
96 | 1x |
has_fraction_in_any_col( |
97 | 1x |
atleast = atleast |
98 |
) |
|
99 |
) |
|
100 |
) |
|
101 | ||
102 | 1x |
std_postprocessing(tlg_prune) |
103 |
} |
|
104 | ||
105 |
#' `AET10` Table 1 (Default) Most Common (xx%) Adverse Events Preferred Terms Table 1. |
|
106 |
#' |
|
107 |
#' The `AET10` table Include Adverse Events occurring with user-specified threshold X% in at least |
|
108 |
#' one of the treatment groups. Standard table summarized by preferred term (PT). |
|
109 |
#' Order the data by total column frequency from most to least frequently reported PT (regardless of SOC). |
|
110 |
#' |
|
111 |
#' @include chevron_tlg-S4class.R |
|
112 |
#' @export |
|
113 |
#' |
|
114 |
#' @examples |
|
115 |
#' run(aet10, syn_data) |
|
116 |
aet10 <- chevron_t( |
|
117 |
main = aet10_main, |
|
118 |
preprocess = aet10_pre, |
|
119 |
postprocess = aet10_post |
|
120 |
) |
1 |
.onLoad <- function(libname, pkgname) { |
|
2 | ! |
tern::set_default_na_str("NE") |
3 |
} |
1 |
# cml02a_gl_main ---- |
|
2 | ||
3 |
#' @describeIn cml02a_gl Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @returns the main function returns an `rlistings` or a `list` object. |
|
7 |
#' @export |
|
8 |
#' |
|
9 |
cml02a_gl_main <- modify_default_args(std_listing, |
|
10 |
dataset = "adcm", |
|
11 |
key_cols = c("ATC2", "CMDECOD"), |
|
12 |
disp_cols = c("ATC2", "CMDECOD", "CMTRT"), |
|
13 |
split_into_pages_by_var = NULL, |
|
14 |
unique_rows = TRUE |
|
15 |
) |
|
16 | ||
17 |
#' @describeIn cml02a_gl Preprocessing |
|
18 |
#' |
|
19 |
#' @inheritParams cml02a_gl_main |
|
20 |
#' @inheritParams gen_args |
|
21 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
22 |
#' |
|
23 |
#' @export |
|
24 |
#' |
|
25 |
cml02a_gl_pre <- function(adam_db, |
|
26 |
dataset = "adcm", |
|
27 |
disp_cols = c("ATC2", "CMDECOD", "CMTRT"), |
|
28 |
...) { |
|
29 | 1x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
30 | 1x |
mutate(across(all_of(disp_cols), ~ reformat(.x, nocoding))) %>% |
31 | 1x |
mutate( |
32 | 1x |
ATC2 = with_label(.data$ATC2, "ATC Class Level 2"), |
33 | 1x |
CMDECOD = with_label(.data$CMDECOD, "WHODrug Preferred Name"), |
34 | 1x |
CMTRT = with_label(.data$CMTRT, "Investigator-Specified Treatment Term") |
35 |
) |
|
36 | ||
37 | 1x |
adam_db |
38 |
} |
|
39 | ||
40 |
#' `CML02A_GL` Listing 1 (Default) Concomitant Medication Class Level 2, Preferred Name, and Investigator-Specified |
|
41 |
#' Terms. |
|
42 |
#' |
|
43 |
#' @include chevron_tlg-S4class.R |
|
44 |
#' @export |
|
45 |
#' |
|
46 |
#' @examples |
|
47 |
#' run(cml02a_gl, syn_data) |
|
48 |
cml02a_gl <- chevron_l( |
|
49 |
main = cml02a_gl_main, |
|
50 |
preprocess = cml02a_gl_pre |
|
51 |
) |
1 |
# lbt15 ---- |
|
2 | ||
3 |
#' @describeIn lbt15 Preprocessing |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
7 |
#' @export |
|
8 |
#' |
|
9 |
lbt15_pre <- function(adam_db, ...) { |
|
10 | 1x |
format <- rule( |
11 | 1x |
"LOW" = c("-3", "-4"), |
12 | 1x |
"MODERATE/NORMAL" = c("-2", "-1", "0", "1", "2"), |
13 | 1x |
"HIGH" = c("3", "4"), |
14 | 1x |
.to_NA = NULL |
15 |
) |
|
16 | ||
17 | 1x |
adam_db$adlb <- adam_db$adlb %>% |
18 | 1x |
filter( |
19 | 1x |
.data$ONTRTFL == "Y", |
20 | 1x |
.data$PARCAT2 == "SI" |
21 |
) %>% |
|
22 | 1x |
mutate( |
23 | 1x |
PARAM = with_label(.data$PARAM, "Laboratory Test"), |
24 | 1x |
ANRIND = with_label(.data$ANRIND, "Direction of Abnormality") |
25 |
) %>% |
|
26 | 1x |
mutate( |
27 | 1x |
ANRIND = reformat(.data$ATOXGR, .env$format), |
28 | 1x |
BNRIND = reformat(.data$BTOXGR, .env$format) |
29 |
) |
|
30 | ||
31 | 1x |
adam_db |
32 |
} |
|
33 | ||
34 |
#' `LBT15` Laboratory Test Shifts to `NCI-CTCAE` Grade 3-4 Post-Baseline Table. |
|
35 |
#' @source `lbt04.R` |
|
36 |
#' |
|
37 |
#' @include chevron_tlg-S4class.R |
|
38 |
#' @export |
|
39 |
#' |
|
40 |
#' @examples |
|
41 |
#' run(lbt15, syn_data) |
|
42 |
lbt15 <- chevron_t( |
|
43 |
main = lbt04_main, |
|
44 |
preprocess = lbt15_pre, |
|
45 |
postprocess = lbt04_post |
|
46 |
) |
1 |
# ael03_main ---- |
|
2 | ||
3 |
#' @describeIn ael03 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @returns the main function returns an `rlistings` or a `list` object. |
|
7 |
#' @export |
|
8 |
#' |
|
9 |
ael03_main <- modify_default_args( |
|
10 |
std_listing, |
|
11 |
dataset = "adae", |
|
12 |
key_cols = c("ID", "ASR"), |
|
13 |
disp_cols = c( |
|
14 |
"AEDECOD", "TRTSDTM", "ASTDY", "ADURN", "ASEV", |
|
15 |
"AREL", "AEOUT", "AECONTRT", "AEACN", "SERREAS" |
|
16 |
), |
|
17 |
split_into_pages_by_var = "ACTARM" |
|
18 |
) |
|
19 | ||
20 |
#' @describeIn ael03 Preprocessing |
|
21 |
#' |
|
22 |
#' @inheritParams ael03_main |
|
23 |
#' @inheritParams gen_args |
|
24 |
#' |
|
25 |
#' @export |
|
26 |
#' |
|
27 |
ael03_pre <- function(adam_db, |
|
28 |
dataset = "adae", |
|
29 |
arm_var = "ACTARM", |
|
30 |
...) { |
|
31 | 1x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
32 | 1x |
filter(.data$ANL01FL == "Y") %>% |
33 | 1x |
filter(.data$AESER == "Y") %>% |
34 | 1x |
mutate( |
35 | 1x |
across( |
36 | 1x |
all_of(c(arm_var, "AEDECOD", "ASEV", "AEOUT", "AEACN")), |
37 | 1x |
~ reformat(.x, missing_rule) |
38 |
) |
|
39 |
) %>% |
|
40 | 1x |
mutate( |
41 | 1x |
!!arm_var := with_label(.data[[arm_var]], "Treatment"), |
42 | 1x |
ID = create_id_listings(.data$SITEID, .data$SUBJID), |
43 | 1x |
AEDECOD = with_label(reformat(.data$AEDECOD, nocoding), "Adverse\nEvent MedDRA\nPreferred Term"), |
44 | 1x |
ASR = with_label(paste(.data$AGE, .data$SEX, .data$RACE, sep = "/"), "Age/Sex/Race"), |
45 |
# Datetime of First Exposure to Treatment |
|
46 | 1x |
TRTSDTM = with_label(.data$TRTSDTM, "Date of\nFirst Study\nDrug\nAdministration"), |
47 | 1x |
ASTDY = with_label(.data$ASTDY, "Study\nDay of\nOnset"), |
48 | 1x |
ADURN = with_label(.data$AENDY - .data$ASTDY + 1, "AE\nDuration\nin Days"), |
49 | 1x |
AESER = with_label(.data$AESER, "Serious"), |
50 | 1x |
ASEV = with_label(.data$ASEV, "Most\nExtreme\nIntensity"), |
51 | 1x |
AREL = with_label(reformat(.data$AREL, yes_no_rule), "Caused by\nStudy\nDrug"), # Analysis Causality |
52 | 1x |
AEOUT = with_label(reformat(.data$AEOUT, outcome_rule), "Outcome\n(1)"), |
53 | 1x |
AECONTRT = with_label(reformat(.data$AECONTRT, yes_no_rule), "Treatment\nfor AE"), |
54 | 1x |
AEACN = with_label(reformat(.data$AEACN, dose_change_rule), "Action\nTaken\n(2)"), |
55 |
# New derived column |
|
56 | 1x |
SERREAS = with_label(case_when( |
57 | 1x |
AESDTH == "Y" ~ "1", |
58 | 1x |
AESLIFE == "Y" ~ "2", |
59 | 1x |
AESHOSP == "Y" ~ "3", |
60 | 1x |
AESDISAB == "Y" ~ "4", |
61 | 1x |
AESCONG == "Y" ~ "5", |
62 | 1x |
AESMIE == "Y" ~ "6", |
63 | 1x |
TRUE ~ " " |
64 | 1x |
), "Reason\nClassified\nas Serious\n(3)"), |
65 |
) |
|
66 | ||
67 | 1x |
adam_db |
68 |
} |
|
69 | ||
70 |
#' `AEL03` Listing 1 (Default) Listing of Serious Adverse Events. |
|
71 |
#' |
|
72 |
#' @include chevron_tlg-S4class.R |
|
73 |
#' @export |
|
74 |
#' |
|
75 |
#' @examples |
|
76 |
#' res <- run(ael03, syn_data) |
|
77 |
ael03 <- chevron_l( |
|
78 |
main = ael03_main, |
|
79 |
preprocess = ael03_pre |
|
80 |
) |
1 |
# rmpt06 ---- |
|
2 | ||
3 |
#' @describeIn rmpt06 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param method (`string`) the method used to construct the confidence interval. See [`tern::estimate_proportion`]. |
|
7 |
#' @param conf_level (`proportion`) the confidence level of the interval. See [`tern::estimate_proportion`]. |
|
8 |
#' @param show_diff (`flag`) whether to show the difference of patient with at least one adverse event between groups. |
|
9 |
#' @param ref_group (`string`) the reference group for the difference. |
|
10 |
#' @param method_diff (`string`) the method used to construct the confidence interval for the difference between groups. |
|
11 |
#' @param conf_level_diff (`proportion`) the confidence level of the interval for the difference between groups. |
|
12 |
#' @param grade_groups (`list`) the grade groups to be displayed. |
|
13 |
#' @returns the main function returns an `rtables` object. |
|
14 |
#' |
|
15 |
#' @export |
|
16 |
rmpt06_main <- function(adam_db, |
|
17 |
arm_var = "ACTARM", |
|
18 |
lbl_overall = NULL, |
|
19 |
method = "clopper-pearson", |
|
20 |
conf_level = 0.95, |
|
21 |
show_diff = FALSE, |
|
22 |
ref_group = NULL, |
|
23 |
method_diff = "wald", |
|
24 |
conf_level_diff = 0.95, |
|
25 |
grade_groups = NULL, |
|
26 |
...) { |
|
27 | 2x |
assert_all_tablenames(adam_db, "adsl", "adae") |
28 | 2x |
assert_string(arm_var) |
29 | 2x |
assert_string(lbl_overall, null.ok = TRUE) |
30 | 2x |
assert_choice( |
31 | 2x |
method, |
32 | 2x |
c("waldcc", "wald", "clopper-pearson", "wilson", "wilsonc", "agresti-coull", "jeffreys") |
33 |
) |
|
34 | 2x |
assert_numeric(conf_level, lower = 0, upper = 1) |
35 | 2x |
assert_flag(show_diff) |
36 | 2x |
assert_choice( |
37 | 2x |
method_diff, |
38 | 2x |
c("waldcc", "wald", "cmh", "ha", "newcombe", "newcombecc") |
39 |
) |
|
40 | 2x |
assert_numeric(conf_level_diff, lower = 0, upper = 1) |
41 | 2x |
assert_list(grade_groups, null.ok = TRUE) |
42 | 2x |
assert_valid_variable(adam_db$adsl, "AEFL", types = list("logical")) |
43 | 2x |
assert_valid_variable(adam_db$adae, "ATOXGR", na_ok = TRUE, types = list("factor")) |
44 | 2x |
assert_valid_variable(adam_db$adae, "AESER", types = list("character", "factor")) |
45 | 2x |
assert_valid_variable(adam_db$adae, "AEOUT", na_ok = TRUE, types = list("factor")) |
46 | 2x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var)) |
47 | 2x |
assert_valid_variable(adam_db$adae, c(arm_var), types = list(c("character", "factor"))) |
48 | 2x |
assert_valid_variable(adam_db$adae, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
49 | 2x |
assert_valid_var_pair(adam_db$adsl, adam_db$adae, arm_var) |
50 | ||
51 | 2x |
lbl_overall <- render_safe(lbl_overall) |
52 | ||
53 | 2x |
if (is.null(grade_groups)) { |
54 | 2x |
grade_groups <- list( |
55 | 2x |
"Grade 1" = "1", |
56 | 2x |
"Grade 2" = "2", |
57 | 2x |
"Grade 3" = "3", |
58 | 2x |
"Grade 4" = "4", |
59 | 2x |
"Grade 5 (fatal outcome)" = "5" |
60 |
) |
|
61 |
} |
|
62 | ||
63 | 2x |
ref_group <- ref_group %||% lvls(adam_db$adsl[[arm_var]])[1] |
64 | ||
65 | 2x |
lyt <- rmpt06_lyt( |
66 | 2x |
arm_var = arm_var, |
67 | 2x |
lbl_overall = lbl_overall, |
68 | 2x |
method = method, |
69 | 2x |
ref_group = ref_group, |
70 | 2x |
conf_level = conf_level, |
71 | 2x |
show_diff = show_diff, |
72 | 2x |
method_diff = method_diff, |
73 | 2x |
conf_level_diff = conf_level_diff, |
74 | 2x |
grade_groups = grade_groups |
75 |
) |
|
76 | ||
77 | 2x |
tbl_adsl <- build_table(lyt$adsl, adam_db$adsl) |
78 | 2x |
tbl_adae <- build_table(lyt$adae, adam_db$adae, alt_counts_df = adam_db$adsl) |
79 | ||
80 | 2x |
col_info(tbl_adae) <- col_info(tbl_adsl) |
81 | ||
82 | 2x |
rbind( |
83 | 2x |
tbl_adsl, |
84 | 2x |
tbl_adae |
85 |
) |
|
86 |
} |
|
87 | ||
88 |
#' `rmpt06` Layout |
|
89 |
#' |
|
90 |
#' @inheritParams gen_args |
|
91 |
#' |
|
92 |
#' @keywords internal |
|
93 |
#' |
|
94 |
rmpt06_lyt <- function(arm_var, |
|
95 |
lbl_overall, |
|
96 |
method, |
|
97 |
conf_level, |
|
98 |
show_diff, |
|
99 |
ref_group, |
|
100 |
method_diff, |
|
101 |
conf_level_diff, |
|
102 |
grade_groups) { |
|
103 | 4x |
lyt <- basic_table(show_colcounts = TRUE) %>% |
104 | 4x |
split_cols_by_with_overall(arm_var, lbl_overall, ref_group = ref_group) |
105 | ||
106 | 4x |
lyt_adsl <- lyt %>% |
107 | 4x |
estimate_proportion( |
108 | 4x |
vars = "AEFL", |
109 | 4x |
method = method, |
110 | 4x |
conf_level = conf_level, |
111 | 4x |
.labels = c( |
112 | 4x |
n_prop = render_safe("Number of {patient_label} with at least one adverse event"), |
113 | 4x |
prop_ci = paste0( |
114 | 4x |
100 * conf_level, |
115 | 4x |
render_safe("% CI for % of {patient_label} with at least one AE") |
116 |
) |
|
117 |
), |
|
118 | 4x |
table_names = "est_prop" |
119 |
) |
|
120 | ||
121 | 4x |
if (show_diff) { |
122 | 1x |
lyt_adsl <- lyt_adsl %>% |
123 | 1x |
estimate_proportion_diff( |
124 | 1x |
vars = "AEFL", |
125 | 1x |
method = method_diff, |
126 | 1x |
conf_level = conf_level_diff, |
127 | 1x |
.labels = c( |
128 | 1x |
diff = render_safe("Difference in % of {patient_label} with at least one AE"), |
129 | 1x |
diff_ci = paste0( |
130 | 1x |
100 * conf_level_diff, |
131 | 1x |
"% CI of difference" |
132 |
) |
|
133 |
), |
|
134 | 1x |
table_names = "est_diff" |
135 |
) |
|
136 |
} |
|
137 | ||
138 | 4x |
lyt_adae <- lyt %>% |
139 | 4x |
analyze_num_patients( |
140 | 4x |
vars = "USUBJID", |
141 | 4x |
.stats = c("nonunique"), |
142 | 4x |
.labels = c( |
143 | 4x |
nonunique = "Total number of AEs" |
144 |
), |
|
145 | 4x |
.formats = list(nonunique = "xx"), |
146 | 4x |
show_labels = "hidden" |
147 |
) %>% |
|
148 | 4x |
count_occurrences_by_grade( |
149 | 4x |
var = "ATOXGR", |
150 | 4x |
var_labels = render_safe("Total number of {patient_label} with at least one AE by worst grade"), |
151 | 4x |
show_labels = "visible", |
152 | 4x |
grade_groups = grade_groups |
153 |
) %>% |
|
154 | 4x |
count_patients_with_event( |
155 | 4x |
"USUBJID", |
156 | 4x |
filters = c("AESER" = "Y"), |
157 | 4x |
.labels = c(count_fraction = render_safe("Number of {patient_label} with at least one serious AE")), |
158 | 4x |
denom = "N_col", |
159 | 4x |
.formats = c(count_fraction = format_count_fraction_fixed_dp), |
160 | 4x |
table_names = "aeser" |
161 |
) %>% |
|
162 | 4x |
count_occurrences( |
163 | 4x |
"AEOUT", |
164 | 4x |
denom = "n", |
165 | 4x |
var_labels = render_safe("Number of {patient_label} with at least one AE by outcome"), |
166 | 4x |
show_labels = "visible", |
167 | 4x |
drop = FALSE |
168 |
) |
|
169 | ||
170 | ||
171 | 4x |
list( |
172 | 4x |
adsl = lyt_adsl, |
173 | 4x |
adae = lyt_adae |
174 |
) |
|
175 |
} |
|
176 | ||
177 |
#' @describeIn rmpt06 Preprocessing |
|
178 |
#' |
|
179 |
#' @inheritParams rmpt06_main |
|
180 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
181 |
#' @export |
|
182 |
rmpt06_pre <- function(adam_db, ...) { |
|
183 | 2x |
aeout_rule <- rule( |
184 | 2x |
"Fatal outcome" = "FATAL", |
185 | 2x |
"Unresolved" = "NOT RECOVERED/NOT RESOLVED", |
186 | 2x |
"Recovered/Resolved" = "RECOVERED/RESOLVED", |
187 | 2x |
"Resolved with sequelae" = "RECOVERED/RESOLVED WITH SEQUELAE", |
188 | 2x |
"Recovering/Resolving" = "RECOVERING/RESOLVING", |
189 | 2x |
"Unknown outcome" = "UNKNOWN" |
190 |
) |
|
191 | ||
192 | 2x |
adam_db$adae <- adam_db$adae %>% |
193 | 2x |
filter(.data$ANL01FL == "Y") %>% |
194 | 2x |
mutate(AEOUT = reformat(.data$AEOUT, aeout_rule)) |
195 | ||
196 | 2x |
adam_db$adsl <- adam_db$adsl %>% |
197 | 2x |
mutate(AEFL = .data$USUBJID %in% .env$adam_db$adae$USUBJID) |
198 | ||
199 | 2x |
adam_db |
200 |
} |
|
201 | ||
202 |
#' @describeIn rmpt06 Postprocessing |
|
203 |
#' |
|
204 |
#' @inheritParams gen_args |
|
205 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
206 |
#' @export |
|
207 |
#' |
|
208 |
rmpt06_post <- function(tlg, prune_0 = FALSE, ...) { |
|
209 | ! |
if (prune_0) { |
210 | ! |
tlg <- smart_prune(tlg) |
211 |
} |
|
212 | ! |
std_postprocessing(tlg) |
213 |
} |
|
214 | ||
215 |
#' `RMPT06` Table 1 (Default) Seriousness, Outcomes, Severity, Frequency with 95% CI for Risk Management Plan. |
|
216 |
#' |
|
217 |
#' @include chevron_tlg-S4class.R |
|
218 |
#' @export |
|
219 |
#' |
|
220 |
#' @examples |
|
221 |
#' run(rmpt06, syn_data) |
|
222 |
rmpt06 <- chevron_t( |
|
223 |
main = rmpt06_main, |
|
224 |
preprocess = rmpt06_pre, |
|
225 |
postprocess = rmpt06_post |
|
226 |
) |
1 |
# mht01 ---- |
|
2 | ||
3 |
#' @describeIn mht01 Default labels |
|
4 |
#' @export |
|
5 |
mht01_label <- c( |
|
6 |
unique = "Total number of {patient_label} with at least one condition", |
|
7 |
nonunique = "Total number of conditions" |
|
8 |
) |
|
9 | ||
10 |
#' @describeIn mht01 Main TLG function |
|
11 |
#' |
|
12 |
#' @inheritParams gen_args |
|
13 |
#' @param summary_labels (`list`) of summarize labels. See details. |
|
14 |
#' @returns the main function returns an `rtables` object. |
|
15 |
#' |
|
16 |
#' @details |
|
17 |
#' * Numbers represent absolute numbers of patients and fraction of `N`, or absolute number of event when specified. |
|
18 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
19 |
#' * Split columns by arm. |
|
20 |
#' * Does not include a total column by default. |
|
21 |
#' * Order by `row_split_var` alphabetically and medical condition by decreasing total number of |
|
22 |
#' patients with the specific condition. |
|
23 |
#' `summary_labels` is used to control the summary for each level. If "all" is used, then each split will have that |
|
24 |
#' summary statistic with the labels. One special case is "TOTAL", this is for the overall population. |
|
25 |
#' |
|
26 |
#' @note |
|
27 |
#' * `adam_db` object must contain an `admh` table with columns `"MHBODSYS"` and `"MHDECOD"`. |
|
28 |
#' |
|
29 |
#' @export |
|
30 |
#' |
|
31 |
mht01_main <- function(adam_db, |
|
32 |
arm_var = "ARM", |
|
33 |
row_split_var = "MHBODSYS", |
|
34 |
lbl_overall = NULL, |
|
35 |
summary_labels = list( |
|
36 |
all = mht01_label |
|
37 |
), |
|
38 |
...) { |
|
39 | 1x |
assert_all_tablenames(adam_db, c("admh", "adsl")) |
40 | 1x |
assert_string(arm_var) |
41 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
42 | 1x |
assert_valid_variable( |
43 | 1x |
adam_db$admh, |
44 | 1x |
c(row_split_var, "MHDECOD"), |
45 | 1x |
types = list(c("character", "factor")), |
46 | 1x |
empty_ok = TRUE |
47 |
) |
|
48 | 1x |
assert_valid_variable(adam_db$admh, "USUBJID", types = list(c("character", "factor")), empty_ok = TRUE) |
49 | 1x |
assert_valid_variable(adam_db$adsl, "USUBJID", types = list(c("character", "factor"))) |
50 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$admh, arm_var) |
51 | 1x |
assert_list(summary_labels, null.ok = TRUE) |
52 | 1x |
assert_subset(names(summary_labels), c("all", "TOTAL", row_split_var)) |
53 | 1x |
assert_subset( |
54 | 1x |
unique(unlist(lapply(summary_labels, names))), |
55 | 1x |
c("unique", "nonunique", "unique_count") |
56 |
) |
|
57 | 1x |
summary_labels <- expand_list(summary_labels, c("TOTAL", row_split_var)) |
58 | ||
59 | 1x |
lbl_overall <- render_safe(lbl_overall) |
60 | 1x |
lbl_row_split <- var_labels_for(adam_db$admh, row_split_var) |
61 | 1x |
lbl_mhdecod <- var_labels_for(adam_db$admh, "MHDECOD") |
62 | ||
63 | 1x |
lyt <- occurrence_lyt( |
64 | 1x |
arm_var = arm_var, |
65 | 1x |
lbl_overall = lbl_overall, |
66 | 1x |
row_split_var = row_split_var, |
67 | 1x |
lbl_row_split = lbl_row_split, |
68 | 1x |
medname_var = "MHDECOD", |
69 | 1x |
lbl_medname_var = lbl_mhdecod, |
70 | 1x |
summary_labels = summary_labels, |
71 | 1x |
count_by = "MHSEQ" |
72 |
) |
|
73 | ||
74 | 1x |
tbl <- build_table(lyt, adam_db$admh, alt_counts_df = adam_db$adsl) |
75 | ||
76 | 1x |
tbl |
77 |
} |
|
78 | ||
79 |
#' @describeIn mht01 Preprocessing |
|
80 |
#' |
|
81 |
#' @inheritParams gen_args |
|
82 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
83 |
#' @export |
|
84 |
#' |
|
85 |
mht01_pre <- function(adam_db, ...) { |
|
86 | 1x |
adam_db$admh <- adam_db$admh %>% |
87 | 1x |
filter(.data$ANL01FL == "Y") |
88 | ||
89 | 1x |
adam_db$admh <- adam_db$admh %>% |
90 | 1x |
mutate( |
91 | 1x |
across(all_of(c("MHBODSYS", "MHDECOD")), ~ reformat(.x, nocoding)) |
92 |
) %>% |
|
93 | 1x |
mutate( |
94 | 1x |
MHBODSYS = with_label(.data$MHBODSYS, "MedDRA System Organ Class"), |
95 | 1x |
MHDECOD = with_label(.data$MHDECOD, "MedDRA Preferred Term"), |
96 | 1x |
MHSEQ = as.factor(.data$MHSEQ) |
97 |
) |
|
98 | ||
99 | 1x |
adam_db |
100 |
} |
|
101 | ||
102 |
#' @describeIn mht01 Postprocessing |
|
103 |
#' |
|
104 |
#' @inheritParams gen_args |
|
105 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
106 |
#' @export |
|
107 |
#' |
|
108 |
mht01_post <- function(tlg, row_split_var = "MHBODSYS", prune_0 = TRUE, ...) { |
|
109 | 1x |
if (prune_0) { |
110 | 1x |
tlg <- smart_prune(tlg) |
111 |
} |
|
112 | ||
113 | 1x |
row_split_var <- c(rbind(row_split_var, "*")) |
114 | ||
115 | 1x |
tbl_sorted <- tlg %>% |
116 | 1x |
sort_at_path( |
117 | 1x |
path = c(row_split_var, "MHDECOD"), |
118 | 1x |
scorefun = score_occurrences |
119 |
) |
|
120 | ||
121 | 1x |
std_postprocessing(tbl_sorted) |
122 |
} |
|
123 | ||
124 |
#' `MHT01` Medical History Table. |
|
125 |
#' |
|
126 |
#' The `MHT01` table provides an overview of the subjects medical |
|
127 |
#' history by SOC and Preferred Term. |
|
128 |
#' |
|
129 |
#' @include chevron_tlg-S4class.R |
|
130 |
#' @export |
|
131 |
#' |
|
132 |
#' @examples |
|
133 |
#' run(mht01, syn_data) |
|
134 |
mht01 <- chevron_t( |
|
135 |
main = mht01_main, |
|
136 |
preprocess = mht01_pre, |
|
137 |
postprocess = mht01_post |
|
138 |
) |
1 |
# aet05_all ---- |
|
2 | ||
3 |
#' @describeIn aet05_all Preprocessing |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
7 |
#' @export |
|
8 |
#' |
|
9 |
aet05_all_pre <- function(adam_db, dataset = "adsaftte", ...) { |
|
10 | 1x |
anl_tte <- adam_db[[dataset]] %>% |
11 | 1x |
filter(.data$PARAMCD == "AEREPTTE") %>% |
12 | 1x |
select(all_of(c("USUBJID", "AVAL"))) |
13 | ||
14 | 1x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
15 | 1x |
filter(grepl("TOT", .data$PARAMCD)) %>% |
16 | 1x |
mutate( |
17 | 1x |
N_EVENTS = as.integer(.data$AVAL), |
18 | 1x |
AVAL = NULL |
19 |
) %>% |
|
20 | 1x |
left_join(anl_tte, by = c("USUBJID")) |
21 | ||
22 | 1x |
adam_db |
23 |
} |
|
24 | ||
25 |
#' `AET05_ALL` Table 1 (Default) Adverse Event Rate Adjusted for Patient-Years at Risk - All Occurrences. |
|
26 |
#' |
|
27 |
#' The `AET05_ALL` table produces the standard adverse event rate adjusted for patient-years at risk summary |
|
28 |
#' considering all occurrences. |
|
29 |
#' |
|
30 |
#' @include chevron_tlg-S4class.R |
|
31 |
#' @export |
|
32 |
#' |
|
33 |
#' @examples |
|
34 |
#' library(dplyr) |
|
35 |
#' library(dunlin) |
|
36 |
#' |
|
37 |
#' proc_data <- log_filter(syn_data, PARAMCD == "AETOT1" | PARAMCD == "AEREPTTE", "adsaftte") |
|
38 |
#' |
|
39 |
#' run(aet05_all, proc_data) |
|
40 |
#' |
|
41 |
#' run(aet05_all, proc_data, conf_level = 0.90, conf_type = "exact") |
|
42 |
aet05_all <- chevron_t( |
|
43 |
main = aet05_main, |
|
44 |
preprocess = aet05_all_pre, |
|
45 |
postprocess = aet05_post |
|
46 |
) |
1 |
#' No Coding Available rule |
|
2 |
#' @export |
|
3 |
nocoding <- rule("No Coding Available" = c("", NA)) |
|
4 | ||
5 |
#' Missing rule |
|
6 |
#' @export |
|
7 |
missing_rule <- rule("<Missing>" = c("", NA), .drop = TRUE) |
|
8 | ||
9 |
#' Empty rule |
|
10 |
#' @export |
|
11 |
empty_rule <- rule(.to_NA = "") |
|
12 | ||
13 |
#' Yes/No rule in title case |
|
14 |
#' @export |
|
15 |
yes_no_rule <- rule("Yes" = c("Y", "YES", "y", "yes"), "No" = c("N", "NO", "n", "no")) # nolint |
|
16 | ||
17 |
#' Outcome Rule |
|
18 |
#' @export |
|
19 |
outcome_rule <- rule( |
|
20 |
"1" = "FATAL", |
|
21 |
"2" = "NOT RECOVERED/NOT RESOLVED", |
|
22 |
"3" = "RECOVERED/RESOLVED", |
|
23 |
"4" = "RECOVERED/RESOLVED WITH SEQUELAE", |
|
24 |
"5" = "RECOVERING/RESOLVING", |
|
25 |
"6" = "UNKNOWN" |
|
26 |
) |
|
27 | ||
28 |
#' Dose Change Rule |
|
29 |
#' @export |
|
30 |
dose_change_rule <- rule( |
|
31 |
"1" = "DOSE INCREASED", |
|
32 |
"2" = "DOSE NOT CHANGED", |
|
33 |
"3" = c("DOSE REDUCED", "DOSE RATE REDUCED"), |
|
34 |
"4" = "DRUG INTERRUPTED", |
|
35 |
"5" = "DRUG WITHDRAWN", |
|
36 |
"6" = c("NOT APPLICABLE", "NOT EVALUABLE"), |
|
37 |
"7" = "UNKNOWN" |
|
38 |
) |
|
39 | ||
40 |
#' Get grade rule |
|
41 |
#' @param direction (`string`) of abnormality direction. |
|
42 |
#' @param missing (`string`) method to deal with missing |
|
43 |
#' @returns a `rule` object. |
|
44 |
#' @export |
|
45 |
get_grade_rule <- function(direction = "high", missing = "incl") { |
|
46 | 14x |
assert_choice(direction, c("high", "low")) |
47 | 14x |
assert_choice(missing, c("incl", "gr_0", "excl")) |
48 | 14x |
rule_arg <- list() |
49 | 14x |
if (direction == "high") { |
50 | 6x |
rule_arg[["Not High"]] <- c("0", "-1", "-2", "-3", "-4") |
51 | 6x |
rule_arg[as.character(1:4)] <- as.character(1:4) |
52 |
} else { |
|
53 | 8x |
rule_arg[["Not Low"]] <- c("0", "1", "2", "3", "4") |
54 | 8x |
rule_arg[as.character(1:4)] <- as.character(-1:-4) |
55 |
} |
|
56 | 14x |
if (missing == "incl") { |
57 | 8x |
rule_arg$Missing <- c(NA, "", "<Missing>") |
58 |
} else if (missing == "gr_0") { |
|
59 | 3x |
rule_arg[[1]] <- c(rule_arg[[1]], NA, "") |
60 |
} |
|
61 | 14x |
rule(.lst = rule_arg) |
62 |
} |
1 |
# fstg02 ---- |
|
2 | ||
3 |
#' @describeIn fstg02 Main TLG Function |
|
4 |
#' |
|
5 |
#' @details |
|
6 |
#' * No overall value. |
|
7 |
#' * Keep zero count rows by default. |
|
8 |
#' |
|
9 |
#' @inheritParams gen_args |
|
10 |
#' @param dataset (`string`) the name of a table in the `adam_db` object. |
|
11 |
#' @param arm_var (`string`) the arm variable name used for group splitting. |
|
12 |
#' @param subgroups (`character`) the subgroups variable name to list baseline risk factors. |
|
13 |
#' @param strata_var (`character`) required if stratified analysis is performed. |
|
14 |
#' @param stat_var (`character`) the names of statistics to be reported in `tabulate_survival_subgroups`. |
|
15 |
#' @param ... Further arguments passed to `g_forest` and `extract_rsp_subgroups` (a wrapper for |
|
16 |
#' `h_odds_ratio_subgroups_df` and `h_proportion_subgroups_df`). For details, see the documentation in `tern`. |
|
17 |
#' Commonly used arguments include `gp`, `col_symbol_size`, `col`, `vline`, `groups_lists`, `conf_level`, |
|
18 |
#' `method`, `label_all`, etc. |
|
19 |
#' @returns the main function returns a `gTree` object. |
|
20 |
#' |
|
21 |
#' @note |
|
22 |
#' * `adam_db` object must contain the table specified by `dataset` with `"PARAMCD"`, `"ARM"`, |
|
23 |
#' `"AVAL"`, `"AVALU"`, `"CNSR"`, and the columns specified by `subgroups` which is denoted as |
|
24 |
#' `c("SEX", "AGEGR1", "RACE")` by default. |
|
25 |
#' * If the plot is too large to be rendered in the output, please refer to `FSTG01`. |
|
26 |
#' |
|
27 |
#' @returns a `gTree` object. |
|
28 |
#' |
|
29 |
#' @export |
|
30 |
#' |
|
31 |
fstg02_main <- function(adam_db, |
|
32 |
dataset = "adtte", |
|
33 |
arm_var = "ARM", |
|
34 |
subgroups = c("SEX", "AGEGR1", "RACE"), |
|
35 |
strata_var = NULL, |
|
36 |
stat_var = c("n_tot", "n", "median", "hr", "ci"), |
|
37 |
...) { |
|
38 | 1x |
assert_all_tablenames(adam_db, c("adsl", dataset)) |
39 | 1x |
df_lbl <- paste0("adam_db$", dataset) |
40 | 1x |
assert_string(arm_var) |
41 | 1x |
assert_character(subgroups, null.ok = TRUE) |
42 | 1x |
assert_character(strata_var, null.ok = TRUE) |
43 | 1x |
assert_character(stat_var, null.ok = TRUE) |
44 | 1x |
assert_valid_variable(adam_db[[dataset]], arm_var, types = list("factor"), n.levels = 2, label = df_lbl) |
45 | 1x |
assert_valid_variable(adam_db[[dataset]], c("USUBJID", "PARAMCD", "AVALU"), |
46 | 1x |
types = list(c("character", "factor")), |
47 | 1x |
label = df_lbl |
48 |
) |
|
49 | 1x |
assert_valid_variable(adam_db[[dataset]], "AVAL", types = list("numeric"), lower = 0, label = df_lbl) |
50 | 1x |
assert_valid_variable(adam_db[[dataset]], "IS_EVENT", types = list("logical"), label = df_lbl) |
51 | 1x |
assert_valid_variable(adam_db[[dataset]], c(subgroups, strata_var), |
52 | 1x |
types = list(c("factor")), na_ok = TRUE, |
53 | 1x |
label = df_lbl |
54 |
) |
|
55 | 1x |
assert_single_value(adam_db[[dataset]]$PARAMCD, label = df_lbl) |
56 | 1x |
assert_single_value(adam_db[[dataset]]$AVALU, label = df_lbl) |
57 | ||
58 | 1x |
timeunit <- unique(adam_db[[dataset]]$AVALU) |
59 | ||
60 | 1x |
variables <- list( |
61 | 1x |
arm = arm_var, |
62 | 1x |
tte = "AVAL", |
63 | 1x |
is_event = "IS_EVENT", |
64 | 1x |
subgroups = subgroups, |
65 | 1x |
strata = strata_var |
66 |
) |
|
67 | ||
68 | 1x |
df <- execute_with_args(extract_survival_subgroups, |
69 | 1x |
variables = variables, |
70 | 1x |
data = adam_db[[dataset]], |
71 |
... |
|
72 |
) |
|
73 | 1x |
result <- basic_table() %>% |
74 | 1x |
tabulate_survival_subgroups(df, vars = stat_var, time_unit = timeunit) |
75 | 1x |
execute_with_args( |
76 | 1x |
g_forest, |
77 | 1x |
tbl = result, |
78 |
..., |
|
79 | 1x |
font_size = 7 |
80 |
) |
|
81 |
} |
|
82 | ||
83 |
#' @describeIn fstg02 Preprocessing |
|
84 |
#' |
|
85 |
#' @inheritParams fstg02_main |
|
86 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
87 |
#' |
|
88 |
#' @export |
|
89 |
#' |
|
90 |
fstg02_pre <- function(adam_db, ...) { |
|
91 | 1x |
adam_db$adtte <- adam_db$adtte %>% |
92 | 1x |
mutate( |
93 | 1x |
ARM = droplevels(.data$ARM), |
94 | 1x |
AVAL = convert_to_month(.data$AVAL, .data$AVALU), |
95 | 1x |
AVALU = "MONTHS", |
96 | 1x |
IS_EVENT = .data$CNSR == 0 |
97 |
) |
|
98 | 1x |
adam_db |
99 |
} |
|
100 | ||
101 |
# `fstg02` Pipeline ---- |
|
102 | ||
103 |
#' `FSTG02` Subgroup Analysis of Survival Duration. |
|
104 |
#' |
|
105 |
#' The template produces the subgroup analysis of survival duration graphic. |
|
106 |
#' |
|
107 |
#' @include chevron_tlg-S4class.R |
|
108 |
#' @export |
|
109 |
#' |
|
110 |
#' @examples |
|
111 |
#' library(dplyr) |
|
112 |
#' library(dunlin) |
|
113 |
#' |
|
114 |
#' proc_data <- log_filter( |
|
115 |
#' syn_data, |
|
116 |
#' PARAMCD == "OS" & ARM %in% c("A: Drug X", "B: Placebo"), "adtte" |
|
117 |
#' ) |
|
118 |
#' run(fstg02, proc_data, |
|
119 |
#' subgroups = c("SEX", "AGEGR1", "RACE"), |
|
120 |
#' conf_level = 0.90, dataset = "adtte" |
|
121 |
#' ) |
|
122 |
fstg02 <- chevron_g( |
|
123 |
main = fstg02_main, |
|
124 |
preprocess = fstg02_pre |
|
125 |
) |
1 |
# aet02 ---- |
|
2 | ||
3 |
#' @describeIn aet02 Default labels |
|
4 |
#' @export |
|
5 |
#' |
|
6 |
aet02_label <- c( |
|
7 |
unique = "Total number of {patient_label} with at least one adverse event", |
|
8 |
nonunique = "Total number of events" |
|
9 |
) |
|
10 | ||
11 |
#' @describeIn aet02 Main TLG function |
|
12 |
#' |
|
13 |
#' @inheritParams gen_args |
|
14 |
#' @param summary_labels (`list`) of summarize labels. See details. |
|
15 |
#' @returns the main function returns an `rtables` object. |
|
16 |
#' |
|
17 |
#' @details |
|
18 |
#' * Numbers represent absolute numbers of subject and fraction of `N`, or absolute number of event when specified. |
|
19 |
#' * Remove zero-count rows unless overridden with `prune_0 = FALSE`. |
|
20 |
#' * Split columns by arm. |
|
21 |
#' * Does not include a total column by default. |
|
22 |
#' * Sort Dictionary-Derived Code (`AEDECOD`) by highest overall frequencies. |
|
23 |
#' * Missing values in `AEBODSYS`, and `AEDECOD` are labeled by `No Coding Available`. |
|
24 |
#' `summary_labels` is used to control the summary for each level. If "all" is used, then each split will have that |
|
25 |
#' summary statistic with the labels. One special case is "TOTAL", this is for the overall population. |
|
26 |
#' |
|
27 |
#' @note |
|
28 |
#' * `adam_db` object must contain an `adae` table with the columns `"AEBODSYS"` and `"AEDECOD"`. |
|
29 |
#' |
|
30 |
#' @export |
|
31 |
#' |
|
32 |
aet02_main <- function(adam_db, |
|
33 |
arm_var = "ACTARM", |
|
34 |
row_split_var = "AEBODSYS", |
|
35 |
lbl_overall = NULL, |
|
36 |
summary_labels = list( |
|
37 |
all = aet02_label, |
|
38 |
TOTAL = c(nonunique = "Overall total number of events") |
|
39 |
), |
|
40 |
...) { |
|
41 | 1x |
assert_all_tablenames(adam_db, "adsl", "adae") |
42 | 1x |
assert_string(arm_var) |
43 | 1x |
assert_character(row_split_var, null.ok = TRUE) |
44 | 1x |
assert_string(lbl_overall, null.ok = TRUE) |
45 | 1x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
46 | 1x |
assert_valid_variable(adam_db$adae, c(arm_var, row_split_var, "AEDECOD"), types = list(c("character", "factor"))) |
47 | 1x |
assert_valid_variable(adam_db$adae, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
48 | 1x |
assert_valid_var_pair(adam_db$adsl, adam_db$adae, arm_var) |
49 | 1x |
assert_list(summary_labels, null.ok = TRUE) |
50 | 1x |
assert_subset(names(summary_labels), c("all", "TOTAL", row_split_var)) |
51 | 1x |
assert_subset( |
52 | 1x |
unique(unlist(lapply(summary_labels, names))), |
53 | 1x |
c("unique", "nonunique", "unique_count") |
54 |
) |
|
55 | 1x |
summary_labels <- expand_list(summary_labels, c("TOTAL", row_split_var)) |
56 | ||
57 | 1x |
lbl_overall <- render_safe(lbl_overall) |
58 | 1x |
lbl_row_split <- var_labels_for(adam_db$adae, row_split_var) |
59 | 1x |
lbl_aedecod <- var_labels_for(adam_db$adae, "AEDECOD") |
60 | ||
61 | 1x |
lyt <- occurrence_lyt( |
62 | 1x |
arm_var = arm_var, |
63 | 1x |
lbl_overall = lbl_overall, |
64 | 1x |
row_split_var = row_split_var, |
65 | 1x |
lbl_row_split = lbl_row_split, |
66 | 1x |
medname_var = "AEDECOD", |
67 | 1x |
lbl_medname_var = lbl_aedecod, |
68 | 1x |
summary_labels = summary_labels, |
69 | 1x |
count_by = NULL |
70 |
) |
|
71 | ||
72 | 1x |
tbl <- build_table(lyt, adam_db$adae, alt_counts_df = adam_db$adsl) |
73 | ||
74 | 1x |
tbl |
75 |
} |
|
76 | ||
77 |
#' @describeIn aet02 Preprocessing |
|
78 |
#' |
|
79 |
#' @inheritParams gen_args |
|
80 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
81 |
#' @export |
|
82 |
#' |
|
83 |
aet02_pre <- function(adam_db, row_split_var = "AEBODSYS", ...) { |
|
84 | 1x |
adam_db$adae <- adam_db$adae %>% |
85 | 1x |
filter(.data$ANL01FL == "Y") %>% |
86 | 1x |
mutate(AEDECOD = reformat(.data$AEDECOD, nocoding)) %>% |
87 | 1x |
mutate(across(all_of(row_split_var), ~ reformat(.x, nocoding))) |
88 | ||
89 | 1x |
adam_db |
90 |
} |
|
91 | ||
92 |
#' @describeIn aet02 Postprocessing |
|
93 |
#' |
|
94 |
#' @inheritParams gen_args |
|
95 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
96 |
#' @export |
|
97 |
#' |
|
98 |
aet02_post <- function(tlg, row_split_var = "AEBODSYS", prune_0 = TRUE, ...) { |
|
99 | 1x |
tlg <- tlg %>% |
100 | 1x |
tlg_sort_by_vars(row_split_var, cont_n_allcols) %>% |
101 | 1x |
valid_sort_at_path( |
102 | 1x |
path = c(get_sort_path(c(row_split_var, "AEDECOD"))), |
103 | 1x |
scorefun = score_occurrences |
104 |
) |
|
105 | 1x |
if (prune_0) { |
106 | 1x |
tlg <- smart_prune(tlg) |
107 |
} |
|
108 | 1x |
std_postprocessing(tlg) |
109 |
} |
|
110 | ||
111 |
#' `AET02` Table 1 (Default) Adverse Events by System Organ Class and Preferred Term Table 1. |
|
112 |
#' |
|
113 |
#' The `AET02` table provides an overview of the number of subjects experiencing adverse events and the number of advert |
|
114 |
#' events categorized by Body System and Dictionary-Derived Term. |
|
115 |
#' |
|
116 |
#' @include chevron_tlg-S4class.R |
|
117 |
#' @export |
|
118 |
#' |
|
119 |
#' @examples |
|
120 |
#' run(aet02, syn_data) |
|
121 |
aet02 <- chevron_t( |
|
122 |
main = aet02_main, |
|
123 |
preprocess = aet02_pre, |
|
124 |
postprocess = aet02_post |
|
125 |
) |
1 |
#' @include utils.R |
|
2 |
#' @include report_null.R |
|
3 | ||
4 |
# Chevron_tlg ---- |
|
5 | ||
6 |
#' `chevron_tlg` class |
|
7 |
#' |
|
8 |
#' The `chevron_tlg` S4 class associates a `preprocess` function, a main `tlg` function and a `postprocess` function. |
|
9 |
#' |
|
10 |
#' @slot main (`function`) returning a `tlg`. Typically one of the `*_main` function from `chevron`. |
|
11 |
#' @slot preprocess (`function`) returning a pre-processed `list` of `data.frames` amenable to `tlg` creation. Typically |
|
12 |
#' one of the `*_pre` function from `chevron`. |
|
13 |
#' @slot postprocess (`function`) returning a post-processed `tlg`. Typically one of the `*_post` function from |
|
14 |
#' `chevron`. |
|
15 |
#' |
|
16 |
#' @format NULL |
|
17 |
#' |
|
18 |
#' @note To ensure the correct execution of the workflow, additional validation criteria are: |
|
19 |
#' * the first argument of the `main` function must be `adam_db`, the input `list` of `data.frames` to pre-process. The |
|
20 |
#' `...` argument is mandatory. |
|
21 |
#' * the first argument of the `preprocess` function must be `adam_db`, the input `list` of `data.frames` to create |
|
22 |
#' `tlg` output. The `...` argument is mandatory. |
|
23 |
#' * the first argument of the `postprocess` function must be `tlg`, the input `TableTree` object to post-process. The |
|
24 |
#' `...` argument is mandatory. |
|
25 |
#' |
|
26 |
#' @name chevron_tlg-class |
|
27 |
#' @exportClass chevron_tlg |
|
28 |
.chevron_tlg <- setClass( |
|
29 |
"chevron_tlg", |
|
30 |
contains = "VIRTUAL", |
|
31 |
slots = c( |
|
32 |
main = "function", |
|
33 |
preprocess = "function", |
|
34 |
postprocess = "function" |
|
35 |
) |
|
36 |
) |
|
37 | ||
38 |
# Validation ---- |
|
39 | ||
40 |
methods::setValidity("chevron_tlg", function(object) { |
|
41 |
coll <- makeAssertCollection() |
|
42 |
assert_function(object@main, args = c("adam_db"), ordered = TRUE, add = coll) |
|
43 |
assert_function(object@main, args = "...", add = coll) |
|
44 |
assert_function(object@preprocess, args = c("adam_db"), ordered = TRUE, add = coll) |
|
45 |
assert_function(object@preprocess, args = "...", add = coll) |
|
46 |
assert_function(object@postprocess, args = c("tlg"), ordered = TRUE, add = coll) |
|
47 |
assert_function(object@postprocess, args = "...", add = coll) |
|
48 |
reportAssertions(coll) |
|
49 |
}) |
|
50 | ||
51 |
# Subclasses ---- |
|
52 | ||
53 |
## chevron_t ---- |
|
54 | ||
55 |
#' `chevron_t` |
|
56 |
#' |
|
57 |
#' `chevron_t`, a subclass of [chevron::chevron_tlg-class] with specific validation criteria to handle table creation |
|
58 |
#' |
|
59 |
#' @aliases chevron_table |
|
60 |
#' @rdname chevron_tlg-class |
|
61 |
#' @exportClass chevron_t |
|
62 |
.chevron_t <- setClass( |
|
63 |
"chevron_t", |
|
64 |
contains = "chevron_tlg" |
|
65 |
) |
|
66 | ||
67 |
## chevron_l ---- |
|
68 | ||
69 |
#' `chevron_l` |
|
70 |
#' |
|
71 |
#' `chevron_l`, a subclass of [chevron::chevron_tlg-class] with specific validation criteria to handle listing creation |
|
72 |
#' |
|
73 |
#' @aliases chevron_listing |
|
74 |
#' @rdname chevron_tlg-class |
|
75 |
#' @exportClass chevron_l |
|
76 |
.chevron_l <- setClass( |
|
77 |
"chevron_l", |
|
78 |
contains = "chevron_tlg" |
|
79 |
) |
|
80 | ||
81 |
## chevron_g ---- |
|
82 | ||
83 |
#' `chevron_g` |
|
84 |
#' |
|
85 |
#' `chevron_g`, a subclass of [chevron::chevron_tlg-class] with specific validation criteria to handle graph creation |
|
86 |
#' |
|
87 |
#' @aliases chevron_graph |
|
88 |
#' @rdname chevron_tlg-class |
|
89 |
#' @exportClass chevron_g |
|
90 |
.chevron_g <- setClass( |
|
91 |
"chevron_g", |
|
92 |
contains = "chevron_tlg" |
|
93 |
) |
|
94 | ||
95 |
## chevron_simple ---- |
|
96 | ||
97 |
#' `chevron_simple` |
|
98 |
#' |
|
99 |
#' `chevron_simple`, a subclass of [chevron::chevron_tlg-class], where main function is a simple call |
|
100 |
#' |
|
101 |
#' @aliases chevron_simple |
|
102 |
#' @rdname chevron_tlg-class |
|
103 |
#' @exportClass chevron_simple |
|
104 |
.chevron_simple <- setClass( |
|
105 |
"chevron_simple", |
|
106 |
contains = "chevron_tlg" |
|
107 |
) |
|
108 | ||
109 | ||
110 |
# Validity of class `chevron_simple` |
|
111 |
methods::setValidity("chevron_simple", function(object) { |
|
112 |
main_body <- body(object@main) |
|
113 |
if (is.symbol(main_body)) { |
|
114 |
return(invisible(TRUE)) |
|
115 |
} |
|
116 |
res <- rapply(to_list(main_body), function(x) { |
|
117 |
identical(x, as.name("return")) |
|
118 |
}) |
|
119 |
has_return <- if (any(res)) "Must be a simple expression without `return`" else TRUE |
|
120 |
makeAssertion(object@main, has_return, var.name = "object@main", collection = NULL) |
|
121 |
invisible(TRUE) |
|
122 |
}) |
|
123 | ||
124 |
# Sub Constructor ---- |
|
125 | ||
126 |
#' `chevron_t` constructor |
|
127 |
#' |
|
128 |
#' @rdname chevron_tlg-class |
|
129 |
#' |
|
130 |
#' @inheritParams gen_args |
|
131 |
#' @param ... not used |
|
132 |
#' @returns a `chevron_t` class object. |
|
133 |
#' |
|
134 |
#' @export |
|
135 |
#' |
|
136 |
#' @examples |
|
137 |
#' chevron_t_obj <- chevron_t() |
|
138 |
#' chevron_t_obj <- chevron_t(postprocess = function(tlg, indent, ...) { |
|
139 |
#' rtables::table_inset(tlg) <- indent |
|
140 |
#' tlg |
|
141 |
#' }) |
|
142 |
#' |
|
143 |
chevron_t <- function(main = function(adam_db, ...) build_table(basic_table(), adam_db[[1]]), |
|
144 |
preprocess = function(adam_db, ...) adam_db, |
|
145 |
postprocess = std_postprocessing, |
|
146 |
...) { |
|
147 | 2x |
res <- .chevron_t( |
148 | 2x |
main = main, |
149 | 2x |
preprocess = preprocess, |
150 | 2x |
postprocess = postprocess |
151 |
) |
|
152 | ||
153 | 2x |
res |
154 |
} |
|
155 | ||
156 |
#' `chevron_l` constructor |
|
157 |
#' |
|
158 |
#' @rdname chevron_tlg-class |
|
159 |
#' |
|
160 |
#' @inheritParams gen_args |
|
161 |
#' @param ... not used |
|
162 |
#' @returns a `chevron_l` class object. |
|
163 |
#' @export |
|
164 |
#' |
|
165 |
#' @examples |
|
166 |
#' chevron_l_obj <- chevron_l() |
|
167 |
#' |
|
168 |
chevron_l <- function(main = function(adam_db, ...) data.frame(), |
|
169 |
preprocess = function(adam_db, ...) adam_db, |
|
170 |
postprocess = std_postprocessing, |
|
171 |
...) { |
|
172 | 1x |
res <- .chevron_l( |
173 | 1x |
main = main, |
174 | 1x |
preprocess = preprocess, |
175 | 1x |
postprocess = postprocess |
176 |
) |
|
177 | ||
178 | 1x |
res |
179 |
} |
|
180 | ||
181 |
#' `chevron_g` constructor |
|
182 |
#' |
|
183 |
#' @rdname chevron_tlg-class |
|
184 |
#' |
|
185 |
#' @inheritParams gen_args |
|
186 |
#' @param ... not used |
|
187 |
#' @returns a `chevron_g` class object. |
|
188 |
#' |
|
189 |
#' @export |
|
190 |
#' |
|
191 |
#' @examples |
|
192 |
#' chevron_g_obj <- chevron_g() |
|
193 |
#' chevron_g_obj <- chevron_g( |
|
194 |
#' postprocess = function(tlg, title, ...) tlg + ggplot2::labs(main = title) |
|
195 |
#' ) |
|
196 |
#' |
|
197 |
chevron_g <- function(main = function(adam_db, ...) ggplot2::ggplot(), |
|
198 |
preprocess = function(adam_db, ...) adam_db, |
|
199 |
postprocess = std_postprocessing, |
|
200 |
...) { |
|
201 | 1x |
res <- .chevron_g( |
202 | 1x |
main = main, |
203 | 1x |
preprocess = preprocess, |
204 | 1x |
postprocess = postprocess |
205 |
) |
|
206 | ||
207 | 1x |
res |
208 |
} |
|
209 | ||
210 |
#' `chevron_simple` constructor |
|
211 |
#' |
|
212 |
#' @rdname chevron_tlg-class |
|
213 |
#' |
|
214 |
#' @inheritParams gen_args |
|
215 |
#' @param ... not used |
|
216 |
#' @returns a `chevron_simple` class object. |
|
217 |
#' |
|
218 |
#' @export |
|
219 |
#' |
|
220 |
#' @examples |
|
221 |
#' chevron_simple_obj <- chevron_simple() |
|
222 |
chevron_simple <- function() { |
|
223 | 3x |
res <- .chevron_simple( |
224 | 3x |
main = \(adam_db, ...) basic_table() %>% build_table(data.frame()), |
225 | 3x |
preprocess = \(adam_db, ...) adam_db, |
226 | 3x |
postprocess = \(tlg, ...) tlg |
227 |
) |
|
228 | 3x |
res |
229 |
} |
1 |
# egt02_1 ---- |
|
2 | ||
3 |
#' @describeIn egt02_1 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @param exclude_base_abn (`flag`) whether baseline abnormality should be excluded. |
|
7 |
#' @returns the main function returns an `rtables` object |
|
8 |
#' |
|
9 |
#' @details |
|
10 |
#' * Only count LOW or HIGH values. |
|
11 |
#' * Results of "LOW LOW" are treated as the same as "LOW", and "HIGH HIGH" the same as "HIGH". |
|
12 |
#' * Does not include a total column by default. |
|
13 |
#' * Does not remove zero-count rows unless overridden with `prune_0 = TRUE`. |
|
14 |
#' |
|
15 |
#' @note |
|
16 |
#' * `adam_db` object must contain an `adeg` table with the `"PARAM"`, `"ANRIND"` and `"BNRIND"` columns. |
|
17 |
#' |
|
18 |
#' @export |
|
19 |
#' |
|
20 |
egt02_1_main <- function(adam_db, |
|
21 |
arm_var = "ACTARM", |
|
22 |
lbl_overall = NULL, |
|
23 |
exclude_base_abn = FALSE, |
|
24 |
...) { |
|
25 | 2x |
assert_all_tablenames(adam_db, c("adsl", "adeg")) |
26 | 2x |
assert_string(arm_var) |
27 | 2x |
assert_string(lbl_overall, null.ok = TRUE) |
28 | 2x |
assert_flag(exclude_base_abn) |
29 | 2x |
assert_valid_variable(adam_db$adeg, c("PARAM"), types = list(c("character", "factor")), na_ok = FALSE) |
30 | 2x |
assert_valid_variable(adam_db$adeg, c("ANRIND", "BNRIND"), types = list(c("character", "factor")), na_ok = TRUE) |
31 | 2x |
assert_valid_var_pair(adam_db$adsl, adam_db$adeg, arm_var) |
32 | 2x |
assert_valid_variable(adam_db$adeg, "USUBJID", empty_ok = TRUE, types = list(c("character", "factor"))) |
33 | 2x |
assert_valid_variable(adam_db$adsl, c("USUBJID", arm_var), types = list(c("character", "factor"))) |
34 | ||
35 | 2x |
lbl_overall <- render_safe(lbl_overall) |
36 | ||
37 | 2x |
lyt <- egt02_lyt( |
38 | 2x |
arm_var = arm_var, |
39 | 2x |
lbl_overall = lbl_overall, |
40 | 2x |
lbl_vs_assessment = "Assessment", |
41 | 2x |
lbl_vs_abnormality = "Abnormality", |
42 | 2x |
exclude_base_abn = exclude_base_abn |
43 |
) |
|
44 | ||
45 | 2x |
tbl <- build_table(lyt, adam_db$adeg, alt_counts_df = adam_db$adsl) |
46 | ||
47 | 2x |
tbl |
48 |
} |
|
49 | ||
50 |
#' `egt02` Layout |
|
51 |
#' |
|
52 |
#' @inheritParams gen_args |
|
53 |
#' @param lbl_vs_assessment (`string`) the label of the assessment variable. |
|
54 |
#' @param lbl_vs_abnormality (`string`) the label of the abnormality variable. |
|
55 |
#' @param exclude_base_abn (`flag`) whether to exclude subjects with baseline abnormality from numerator and |
|
56 |
#' denominator. |
|
57 |
#' @returns a `PreDataTableLayouts` object. |
|
58 |
#' |
|
59 |
#' @keywords internal |
|
60 |
#' |
|
61 |
egt02_lyt <- function(arm_var = "ACTARM", |
|
62 |
lbl_overall, |
|
63 |
lbl_vs_assessment = "Assessment", |
|
64 |
lbl_vs_abnormality = "Abnormality", |
|
65 |
exclude_base_abn) { |
|
66 | 4x |
basic_table(show_colcounts = TRUE) %>% |
67 | 4x |
split_cols_by_with_overall(arm_var, lbl_overall) %>% |
68 | 4x |
split_rows_by("PARAM", split_fun = drop_split_levels, label_pos = "topleft", split_label = lbl_vs_assessment) %>% |
69 | 4x |
count_abnormal( |
70 | 4x |
"ANRIND", |
71 | 4x |
abnormal = list(Low = "LOW", High = "HIGH"), |
72 | 4x |
variables = list(id = "USUBJID", baseline = "BNRIND"), |
73 | 4x |
exclude_base_abn = exclude_base_abn |
74 |
) %>% |
|
75 | 4x |
append_topleft(paste0(" ", lbl_vs_abnormality)) |
76 |
} |
|
77 | ||
78 |
#' @describeIn egt02_1 Preprocessing |
|
79 |
#' |
|
80 |
#' @inheritParams gen_args |
|
81 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
82 |
#' @export |
|
83 |
#' |
|
84 |
egt02_pre <- function(adam_db, ...) { |
|
85 | 2x |
adam_db$adeg <- adam_db$adeg %>% |
86 | 2x |
mutate(ANRIND = factor(.data$ANRIND, levels = c("LOW", "NORMAL", "HIGH"))) %>% |
87 | 2x |
filter(!is.na(.data$ANRIND)) %>% |
88 | 2x |
filter(.data$ONTRTFL == "Y") |
89 | ||
90 | 2x |
adam_db |
91 |
} |
|
92 | ||
93 |
#' @describeIn egt02_1 Postprocessing |
|
94 |
#' |
|
95 |
#' @inheritParams gen_args |
|
96 |
#' @returns the postprocessing function returns an `rtables` object or an `ElementaryTable` (null report). |
|
97 |
#' @export |
|
98 |
#' |
|
99 |
egt02_post <- function(tlg, ...) { |
|
100 | 2x |
std_postprocessing(tlg) |
101 |
} |
|
102 | ||
103 |
#' `EGT02` ECG Abnormalities Table. |
|
104 |
#' |
|
105 |
#' ECG Parameters outside Normal Limits Regardless of Abnormality at Baseline Table. |
|
106 |
#' |
|
107 |
#' @include chevron_tlg-S4class.R |
|
108 |
#' @export |
|
109 |
#' |
|
110 |
#' @examples |
|
111 |
#' run(egt02_1, syn_data) |
|
112 |
egt02_1 <- chevron_t( |
|
113 |
main = egt02_1_main, |
|
114 |
preprocess = egt02_pre, |
|
115 |
postprocess = egt02_post |
|
116 |
) |
|
117 | ||
118 |
# egt02_2 ---- |
|
119 | ||
120 |
#' @describeIn egt02_2 Main TLG function |
|
121 |
#' |
|
122 |
#' @inherit egt02_1_main |
|
123 |
#' |
|
124 |
#' @export |
|
125 |
#' |
|
126 |
egt02_2_main <- modify_default_args(egt02_1_main, exclude_base_abn = TRUE) |
|
127 | ||
128 |
#' `EGT02_2` ECG Abnormalities Table. |
|
129 |
#' |
|
130 |
#' ECG Parameters outside Normal Limits Among Patients without Abnormality at Baseline Table. |
|
131 |
#' |
|
132 |
#' @include chevron_tlg-S4class.R |
|
133 |
#' @export |
|
134 |
#' |
|
135 |
#' @examples |
|
136 |
#' run(egt02_2, syn_data) |
|
137 |
egt02_2 <- chevron_t( |
|
138 |
main = egt02_2_main, |
|
139 |
preprocess = egt02_pre, |
|
140 |
postprocess = egt02_post |
|
141 |
) |
1 |
# ael01_nollt ---- |
|
2 | ||
3 |
#' @describeIn ael01_nollt Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams std_listing |
|
6 |
#' @returns the main function returns an `rlistings` or a `list` object. |
|
7 |
#' |
|
8 |
#' @details |
|
9 |
#' * Removes duplicate rows. |
|
10 |
#' * By default, uses dataset `adae`, sorting by key columns `AEBODSYS` and `AEDECOD`. |
|
11 |
#' * If using with a dataset other than `adae`, be sure to specify the desired labels for variables in |
|
12 |
#' `key_cols` and `disp_cols`, and pre-process missing data. |
|
13 |
#' |
|
14 |
#' @note |
|
15 |
#' * `adam_db` object must contain the `dataset` table with columns specified by `key_cols` and `disp_cols`. |
|
16 |
#' |
|
17 |
#' @export |
|
18 |
#' |
|
19 |
ael01_nollt_main <- modify_default_args( |
|
20 |
std_listing, |
|
21 |
dataset = "adae", |
|
22 |
key_cols = c("AEBODSYS", "AEDECOD"), |
|
23 |
disp_cols = "AETERM", |
|
24 |
split_into_pages_by_var = NULL, |
|
25 |
unique_rows = TRUE |
|
26 |
) |
|
27 | ||
28 |
#' @describeIn ael01_nollt Preprocessing |
|
29 |
#' |
|
30 |
#' @inheritParams ael01_nollt_main |
|
31 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
32 |
#' |
|
33 |
#' @export |
|
34 |
#' |
|
35 |
ael01_nollt_pre <- function(adam_db, |
|
36 |
dataset = "adae", |
|
37 |
key_cols = c("AEBODSYS", "AEDECOD"), |
|
38 |
disp_cols = "AETERM", |
|
39 |
...) { |
|
40 | 1x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
41 | 1x |
mutate( |
42 | 1x |
across(all_of(c(key_cols, disp_cols)), ~ reformat(.x, nocoding)) |
43 |
) %>% |
|
44 | 1x |
arrange(pick(all_of(c(key_cols, disp_cols)))) |
45 | ||
46 | 1x |
adam_db |
47 |
} |
|
48 | ||
49 |
#' `AEL01_NOLLT` Listing 1 (Default) Glossary of Preferred Terms and Investigator-Specified Terms. |
|
50 |
#' |
|
51 |
#' @include chevron_tlg-S4class.R |
|
52 |
#' @export |
|
53 |
#' |
|
54 |
#' @examples |
|
55 |
#' run(ael01_nollt, syn_data) |
|
56 |
ael01_nollt <- chevron_l( |
|
57 |
main = ael01_nollt_main, |
|
58 |
preprocess = ael01_nollt_pre |
|
59 |
) |
1 |
# ael02_main ---- |
|
2 | ||
3 |
#' @describeIn ael02 Main TLG function |
|
4 |
#' |
|
5 |
#' @inheritParams gen_args |
|
6 |
#' @returns the main function returns an `rlistings` or a `list` object. |
|
7 |
#' @export |
|
8 |
#' |
|
9 |
ael02_main <- modify_default_args(std_listing, |
|
10 |
dataset = "adae", |
|
11 |
key_cols = c("ID", "ASR"), |
|
12 |
disp_cols = c( |
|
13 |
"AEDECOD", "TRTSDTM", "ASTDY", "ADURN", "AESER", |
|
14 |
"ASEV", "AREL", "AEOUT", "AECONTRT", "AEACN" |
|
15 |
), |
|
16 |
split_into_pages_by_var = "ACTARM" |
|
17 |
) |
|
18 | ||
19 |
#' @describeIn ael02 Preprocessing |
|
20 |
#' |
|
21 |
#' @inheritParams ael02_main |
|
22 |
#' @inheritParams gen_args |
|
23 |
#' @returns the preprocessing function returns a `list` of `data.frame`. |
|
24 |
#' @export |
|
25 |
#' |
|
26 |
ael02_pre <- function(adam_db, |
|
27 |
dataset = "adae", |
|
28 |
arm_var = "ACTARM", |
|
29 |
...) { |
|
30 | 1x |
adam_db[[dataset]] <- adam_db[[dataset]] %>% |
31 | 1x |
filter(.data$ANL01FL == "Y") %>% |
32 | 1x |
mutate( |
33 | 1x |
across( |
34 | 1x |
all_of(c(arm_var, "AEDECOD", "ASEV", "AEOUT", "AEACN")), |
35 | 1x |
~ reformat(.x, missing_rule) |
36 |
) |
|
37 |
) %>% |
|
38 | 1x |
mutate( |
39 | 1x |
!!arm_var := with_label(.data[[arm_var]], "Treatment"), |
40 | 1x |
ID = create_id_listings(.data$SITEID, .data$SUBJID), |
41 | 1x |
ASR = with_label(paste(.data$AGE, .data$SEX, .data$RACE, sep = "/"), "Age/Sex/Race"), |
42 | 1x |
TRTSDTM = with_label( |
43 | 1x |
.data$TRTSDTM, |
44 | 1x |
"Date of\nFirst Study\nDrug\nAdministration" |
45 |
), |
|
46 | 1x |
AEDECOD = with_label(reformat(.data$AEDECOD, nocoding), "Adverse\nEvent MedDRA\nPreferred Term"), |
47 | 1x |
ASTDY = with_label(.data$ASTDY, "Study\nDay of\nOnset"), |
48 | 1x |
ADURN = with_label(.data$ADURN, "AE\nDuration\nin Days"), |
49 | 1x |
AESER = with_label(reformat(.data$AESER, yes_no_rule), "Serious"), |
50 | 1x |
ASEV = with_label(.data$ASEV, "Most\nExtreme\nIntensity"), |
51 | 1x |
AREL = with_label(reformat(.data$AREL, yes_no_rule), "Caused by\nStudy\nDrug"), |
52 | 1x |
AEOUT = with_label(reformat(.data$AEOUT, outcome_rule), "Outcome\n(1)"), |
53 | 1x |
AECONTRT = with_label(reformat(.data$AECONTRT, yes_no_rule), "Treatment\nfor AE"), |
54 | 1x |
AEACN = with_label(reformat(.data$AEACN, dose_change_rule), "Action\nTaken\n(2)") |
55 |
) |
|
56 | ||
57 | 1x |
adam_db |
58 |
} |
|
59 | ||
60 |
#' `AEL02` Listing 1 (Default) Listing of Adverse Events. |
|
61 |
#' |
|
62 |
#' @include chevron_tlg-S4class.R |
|
63 |
#' @export |
|
64 |
#' |
|
65 |
#' @examples |
|
66 |
#' res <- run(ael02, syn_data) |
|
67 |
ael02 <- chevron_l( |
|
68 |
main = ael02_main, |
|
69 |
preprocess = ael02_pre |
|
70 |
) |