Skip to content

Commit 2f31365

Browse files
Melkiadesgithub-actions[bot]edelarua
authored
Batch 1 (#1403)
Fixes part of #1381 and #1249 and #1390 --------- Signed-off-by: Davide Garolini <dgarolini@gmail.com> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Emily de la Rua <emily.de_la_rua@contractors.roche.com>
1 parent ec65919 commit 2f31365

29 files changed

+849
-431
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export(analyze_vars_in_cols)
4545
export(append_varlabels)
4646
export(arrange_grobs)
4747
export(as.rtable)
48+
export(as_factor_keep_attributes)
4849
export(combine_counts)
4950
export(combine_groups)
5051
export(combine_levels)

NEWS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
# tern 0.9.7.9012
22

33
### Enhancements
4-
* Refactored `count_abnormal()`, `count_abnormal_by_baseline()`, `count_abnormal_by_marked()`, `count_abnormal_by_worst_grade()`, `count_abnormal_lab_worsen_by_baseline()`, `coxph_pairwise()`, `estimate_multinomial_rsp()`, `estimate_proportion()`, `estimate_odds_ratio()`, `summarize_ancova()`, `summarize_glm_count()`, `summarize_num_patients()`, and `surv_timepoint()` to work without `make_afun()`.
4+
* Refactored `count_abnormal()`, `count_abnormal_by_baseline()`, `count_abnormal_by_marked()`, `count_abnormal_by_worst_grade()`, `count_abnormal_lab_worsen_by_baseline()`, `count_cumulative()`, `count_missed_doses()`, `coxph_pairwise()`, `estimate_multinomial_rsp()`, `estimate_proportion()`, `estimate_proportion_diff()`, `estimate_odds_ratio()`, `summarize_ancova()`, `summarize_glm_count()`, `summarize_num_patients()`, `surv_timepoint()`, and `test_proportion_diff()` to work without `make_afun()`.
55
* Added `geom_sd` and `geom_mean_sd` to `s_summary()` default available statistics.
66
* Refactored `afun_riskdiff()`, `count_occurrences()`, `count_occurrences_by_grade()`, `count_patients_with_event()`, `count_patients_with_flags()`, `count_values()`, `estimate_incidence_rate()`, `h_tab_one_biomarker()`, `summarize_change()`, `summarize_colvars()`, `summarize_patients_exposure_in_cols()`, `survival_time()`, `tabulate_rsp_subgroups()`, `tabulate_survival_subgroups()`, `tabulate_rsp_biomarkers()`, and `tabulate_survival_biomarkers()` to align with new analysis function style.
7+
* Converted `as_factor_keep_attributes()` to an exported function.
78

89
### Bug Fixes
910
* Fixed bug in `a_count_patients_with_flags()` preventing select custom label and indentation specification formats from being applied.
1011
* Fixed bug in `tabulate_rsp_subgroups` and `tabulate_survival_subgroups` preventing the `pct` option from having an effect when adding a risk difference column.
1112
* Fixed bug with the order of `.stats` when adding custom statistical functions.
13+
* Fixed bug with multiple custom functions not being represented correctly as a list of output stats.
1214

1315
### Miscellaneous
1416
* Removed internal function `ungroup_stats()` and replaced its usage with the `get_*_from_stats()` functions.
@@ -19,6 +21,8 @@
1921
* Began deprecation of the no longer used helper functions `h_tab_one_biomarker()`, `h_tab_rsp_one_biomarker()`, and `h_tab_surv_one_biomarker()`.
2022
* Moved helper functions `h_tab_rsp_one_biomarker()` and `h_tab_surv_one_biomarker()` into `h_biomarkers_subgroups.R`.
2123
* Updated documentation to remove suggestions to use `make_afun()`.
24+
* Reorganized the utility documentation related to factors (`utils_factor.R`) into a single file.
25+
* Removed `s_count_nonmissing()` as it is a non-repeated small and internal function.
2226

2327
# tern 0.9.7
2428

R/count_cumulative.R

Lines changed: 114 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,26 @@ NULL
4848
#' x <- c(sample(1:10, 10), NA)
4949
#' .N_col <- length(x)
5050
#'
51-
#' h_count_cumulative(x, 5, .N_col = .N_col)
52-
#' h_count_cumulative(x, 5, lower_tail = FALSE, include_eq = FALSE, na.rm = FALSE, .N_col = .N_col)
53-
#' h_count_cumulative(x, 0, lower_tail = FALSE, .N_col = .N_col)
54-
#' h_count_cumulative(x, 100, lower_tail = FALSE, .N_col = .N_col)
51+
#' h_count_cumulative(x, 5, denom = .N_col)
52+
#' h_count_cumulative(x, 5, lower_tail = FALSE, include_eq = FALSE, na_rm = FALSE, denom = .N_col)
53+
#' h_count_cumulative(x, 0, lower_tail = FALSE, denom = .N_col)
54+
#' h_count_cumulative(x, 100, lower_tail = FALSE, denom = .N_col)
5555
#'
5656
#' @export
5757
h_count_cumulative <- function(x,
5858
threshold,
5959
lower_tail = TRUE,
6060
include_eq = TRUE,
61-
na.rm = TRUE, # nolint
62-
.N_col) { # nolint
61+
na_rm = TRUE,
62+
denom) {
6363
checkmate::assert_numeric(x)
6464
checkmate::assert_numeric(threshold)
65-
checkmate::assert_numeric(.N_col)
65+
checkmate::assert_numeric(denom)
6666
checkmate::assert_flag(lower_tail)
6767
checkmate::assert_flag(include_eq)
68-
checkmate::assert_flag(na.rm)
68+
checkmate::assert_flag(na_rm)
6969

70-
is_keep <- if (na.rm) !is.na(x) else rep(TRUE, length(x))
70+
is_keep <- if (na_rm) !is.na(x) else rep(TRUE, length(x))
7171
count <- if (lower_tail && include_eq) {
7272
length(x[is_keep & x <= threshold])
7373
} else if (lower_tail && !include_eq) {
@@ -80,7 +80,7 @@ h_count_cumulative <- function(x,
8080

8181
result <- c(
8282
count = count,
83-
fraction = if (count == 0 && .N_col == 0) 0 else count / .N_col
83+
fraction = if (count == 0 && denom == 0) 0 else count / denom
8484
)
8585
result
8686
}
@@ -114,9 +114,10 @@ s_count_cumulative <- function(x,
114114
thresholds,
115115
lower_tail = TRUE,
116116
include_eq = TRUE,
117+
denom = c("N_col", "n", "N_row"),
117118
.N_col, # nolint
118119
.N_row, # nolint
119-
denom = c("N_col", "n", "N_row"),
120+
na_rm = TRUE,
120121
...) {
121122
checkmate::assert_numeric(thresholds, min.len = 1, any.missing = FALSE)
122123

@@ -128,7 +129,7 @@ s_count_cumulative <- function(x,
128129
)
129130

130131
count_fraction_list <- Map(function(thres) {
131-
result <- h_count_cumulative(x, thres, lower_tail, include_eq, .N_col = denom, ...)
132+
result <- h_count_cumulative(x, thres, lower_tail, include_eq, na_rm = na_rm, denom = denom)
132133
label <- d_count_cumulative(thres, lower_tail, include_eq)
133134
formatters::with_label(result, label)
134135
}, thresholds)
@@ -144,10 +145,79 @@ s_count_cumulative <- function(x,
144145
#' * `a_count_cumulative()` returns the corresponding list with formatted [rtables::CellValue()].
145146
#'
146147
#' @keywords internal
147-
a_count_cumulative <- make_afun(
148-
s_count_cumulative,
149-
.formats = c(count_fraction = format_count_fraction)
150-
)
148+
a_count_cumulative <- function(x,
149+
...,
150+
.stats = NULL,
151+
.stat_names = NULL,
152+
.formats = NULL,
153+
.labels = NULL,
154+
.indent_mods = NULL) {
155+
dots_extra_args <- list(...)
156+
157+
# Check if there are user-defined functions
158+
default_and_custom_stats_list <- .split_std_from_custom_stats(.stats)
159+
.stats <- default_and_custom_stats_list$all_stats
160+
custom_stat_functions <- default_and_custom_stats_list$custom_stats
161+
162+
# Adding automatically extra parameters to the statistic function (see ?rtables::additional_fun_params)
163+
extra_afun_params <- retrieve_extra_afun_params(
164+
names(dots_extra_args$.additional_fun_parameters)
165+
)
166+
dots_extra_args$.additional_fun_parameters <- NULL # After extraction we do not need them anymore
167+
168+
# Main statistical functions application
169+
x_stats <- .apply_stat_functions(
170+
default_stat_fnc = s_count_cumulative,
171+
custom_stat_fnc_list = custom_stat_functions,
172+
args_list = c(
173+
x = list(x),
174+
extra_afun_params,
175+
dots_extra_args
176+
)
177+
)
178+
179+
# Fill in with stats defaults if needed
180+
.stats <- get_stats("count_cumulative",
181+
stats_in = .stats,
182+
custom_stats_in = names(custom_stat_functions)
183+
)
184+
185+
x_stats <- x_stats[.stats]
186+
levels_per_stats <- lapply(x_stats, names)
187+
188+
# Fill in formats/indents/labels with custom input and defaults
189+
.formats <- get_formats_from_stats(.stats, .formats, levels_per_stats)
190+
.indent_mods <- get_indents_from_stats(.stats, .indent_mods, levels_per_stats)
191+
.labels <- get_labels_from_stats(
192+
.stats, .labels, levels_per_stats,
193+
label_attr_from_stats = sapply(.unlist_keep_nulls(x_stats), attr, "label")
194+
)
195+
196+
# Unlist stats
197+
x_stats <- x_stats %>%
198+
.unlist_keep_nulls() %>%
199+
setNames(names(.formats))
200+
201+
# Auto format handling
202+
.formats <- apply_auto_formatting(
203+
.formats,
204+
x_stats,
205+
extra_afun_params$.df_row,
206+
extra_afun_params$.var
207+
)
208+
209+
# Get and check statistical names from defaults
210+
.stat_names <- get_stat_names(x_stats, .stat_names) # note is x_stats
211+
212+
in_rows(
213+
.list = x_stats,
214+
.formats = .formats,
215+
.names = names(.labels),
216+
.stat_names = .stat_names,
217+
.labels = .labels %>% .unlist_keep_nulls(),
218+
.indent_mods = .indent_mods %>% .unlist_keep_nulls()
219+
)
220+
}
151221

152222
#' @describeIn count_cumulative Layout-creating function which can take statistics function arguments
153223
#' and additional format arguments. This function is a wrapper for [rtables::analyze()].
@@ -178,27 +248,44 @@ count_cumulative <- function(lyt,
178248
show_labels = "visible",
179249
na_str = default_na_str(),
180250
nested = TRUE,
181-
...,
182251
table_names = vars,
183-
.stats = NULL,
252+
...,
253+
na_rm = TRUE,
254+
.stats = c("count_fraction"),
255+
.stat_names = NULL,
184256
.formats = NULL,
185257
.labels = NULL,
186258
.indent_mods = NULL) {
187-
extra_args <- list(thresholds = thresholds, lower_tail = lower_tail, include_eq = include_eq, ...)
259+
# Depending on main functions
260+
extra_args <- list(
261+
"na_rm" = na_rm,
262+
"thresholds" = thresholds,
263+
"lower_tail" = lower_tail,
264+
"include_eq" = include_eq,
265+
...
266+
)
188267

189-
afun <- make_afun(
190-
a_count_cumulative,
191-
.stats = .stats,
192-
.formats = .formats,
193-
.labels = .labels,
194-
.indent_mods = .indent_mods,
195-
.ungroup_stats = "count_fraction"
268+
# Needed defaults
269+
if (!is.null(.stats)) extra_args[[".stats"]] <- .stats
270+
if (!is.null(.stat_names)) extra_args[[".stat_names"]] <- .stat_names
271+
if (!is.null(.formats)) extra_args[[".formats"]] <- .formats
272+
if (!is.null(.labels)) extra_args[[".labels"]] <- .labels
273+
if (!is.null(.indent_mods)) extra_args[[".indent_mods"]] <- .indent_mods
274+
275+
# Adding all additional information from layout to analysis functions (see ?rtables::additional_fun_params)
276+
extra_args[[".additional_fun_parameters"]] <- get_additional_afun_params(add_alt_df = FALSE)
277+
formals(a_count_cumulative) <- c(
278+
formals(a_count_cumulative),
279+
extra_args[[".additional_fun_parameters"]]
196280
)
281+
282+
# Main {rtables} structural call
197283
analyze(
198284
lyt,
199285
vars,
200-
afun = afun,
286+
afun = a_count_cumulative,
201287
na_str = na_str,
288+
inclNAs = !na_rm,
202289
table_names = table_names,
203290
var_labels = var_labels,
204291
show_labels = show_labels,

0 commit comments

Comments
 (0)