Skip to content

Commit 296aeab

Browse files
edelaruashajoezhu
andauthored
Refactor a_count_values() (#1374)
# Pull Request Fixes #1373 --------- Co-authored-by: Joe Zhu <joe.zhu@roche.com>
1 parent 519a04b commit 296aeab

File tree

6 files changed

+175
-18
lines changed

6 files changed

+175
-18
lines changed

NEWS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Added `rel_height_plot` parameter to `g_lineplot()` to control the line plot height relative to annotation table height.
88
* Updated the `table_font_size` parameter of `g_lineplot()` to control the size of all text in the annotation table, including labels.
99
* Added `as_list` parameter to `g_lineplot()` to allow users to return the line plot and annotation table elements as a list instead of stacked for more complex customization.
10-
* Refactored `summarize_change()` to work without `make_afun()` and access all additional function parameter.
10+
* Refactored `summarize_change()` and `count_values()` to work without `make_afun()`.
1111
* Added vignette "Understanding `tern` functions" for future reference.
1212
* Refactored `analyze_vars()` and `a_summary()` to take all options from `?rtables::additional_fun_params`.
1313
* Added to `analyze_vars()` statistical names that are used by `rtables::as_result_df()`.

R/count_values.R

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,61 @@ s_count_values.logical <- function(x, values = TRUE, ...) {
107107
#' a_count_values(x = factor(c("a", "b", "a")), values = "a", .N_col = 10, .N_row = 10)
108108
#'
109109
#' @export
110-
a_count_values <- make_afun(
111-
s_count_values,
112-
.formats = c(count_fraction = "xx (xx.xx%)", count = "xx")
113-
)
110+
a_count_values <- function(x,
111+
...,
112+
.stats = NULL,
113+
.formats = NULL,
114+
.labels = NULL,
115+
.indent_mods = NULL) {
116+
dots_extra_args <- list(...)
117+
118+
# Check for user-defined functions
119+
default_and_custom_stats_list <- .split_std_from_custom_stats(.stats)
120+
.stats <- default_and_custom_stats_list$default_stats
121+
custom_stat_functions <- default_and_custom_stats_list$custom_stats
122+
123+
# Add extra parameters to the s_* function
124+
extra_afun_params <- retrieve_extra_afun_params(
125+
names(dots_extra_args$.additional_fun_parameters)
126+
)
127+
dots_extra_args$.additional_fun_parameters <- NULL
128+
129+
# Main statistic calculations
130+
x_stats <- .apply_stat_functions(
131+
default_stat_fnc = s_count_values,
132+
custom_stat_fnc_list = custom_stat_functions,
133+
args_list = c(
134+
x = list(x),
135+
extra_afun_params,
136+
dots_extra_args
137+
)
138+
)
139+
140+
# Fill in formatting defaults
141+
.stats <- c(
142+
get_stats("analyze_vars_counts", stats_in = .stats),
143+
names(custom_stat_functions) # Additional stats from custom functions
144+
)
145+
.formats <- get_formats_from_stats(.stats, .formats)
146+
.labels <- get_labels_from_stats(.stats, .labels)
147+
.indent_mods <- get_indents_from_stats(.stats, .indent_mods)
148+
149+
# Auto format handling
150+
.formats <- apply_auto_formatting(
151+
.formats,
152+
x_stats,
153+
extra_afun_params$.df_row,
154+
extra_afun_params$.var
155+
)
156+
157+
in_rows(
158+
.list = x_stats[.stats],
159+
.formats = .formats,
160+
.names = names(.labels),
161+
.labels = .labels,
162+
.indent_mods = .indent_mods
163+
)
164+
}
114165

115166
#' @describeIn count_values Layout-creating function which can take statistics function arguments
116167
#' and additional format arguments. This function is a wrapper for [rtables::analyze()].
@@ -132,26 +183,31 @@ count_values <- function(lyt,
132183
vars,
133184
values,
134185
na_str = default_na_str(),
186+
na_rm = TRUE,
135187
nested = TRUE,
136188
...,
137189
table_names = vars,
138190
.stats = "count_fraction",
139-
.formats = NULL,
191+
.formats = c(count_fraction = "xx (xx.xx%)", count = "xx"),
140192
.labels = c(count_fraction = paste(values, collapse = ", ")),
141193
.indent_mods = NULL) {
142-
extra_args <- list(values = values, ...)
194+
# Process extra args
195+
extra_args <- list(".stats" = .stats)
196+
if (!is.null(.formats)) extra_args[[".formats"]] <- .formats
197+
if (!is.null(.labels)) extra_args[[".labels"]] <- .labels
198+
if (!is.null(.indent_mods)) extra_args[[".indent_mods"]] <- .indent_mods
199+
200+
# Add additional arguments to the analysis function
201+
extra_args <- c(extra_args, "na_rm" = na_rm, "values" = list(values), ...)
202+
203+
# Adding additional info from layout to analysis function
204+
extra_args[[".additional_fun_parameters"]] <- get_additional_afun_params(add_alt_df = FALSE)
205+
formals(a_count_values) <- c(formals(a_count_values), extra_args[[".additional_fun_parameters"]])
143206

144-
afun <- make_afun(
145-
a_count_values,
146-
.stats = .stats,
147-
.formats = .formats,
148-
.labels = .labels,
149-
.indent_mods = .indent_mods
150-
)
151207
analyze(
152208
lyt,
153209
vars,
154-
afun = afun,
210+
afun = a_count_values,
155211
na_str = na_str,
156212
nested = nested,
157213
extra_args = extra_args,

man/count_values.Rd

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tern.Rproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
Version: 1.0
2-
ProjectId: 74d75484-65e8-447e-93c0-fca42c4aeacd
32

43
RestoreWorkspace: Default
54
SaveWorkspace: Default

tests/testthat/_snaps/count_values.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,52 @@
298298
0
299299
300300

301+
# count_values works with denom specified
302+
303+
Code
304+
res
305+
Output
306+
all obs
307+
————————————————————
308+
setosa 50 (33.33%)
309+
310+
---
311+
312+
Code
313+
case1
314+
Output
315+
A: Drug X B: Placebo C: Combination
316+
(N=202) (N=177) (N=162)
317+
——————————————————————————————————————————————
318+
Y 80 (39.60%) 69 (38.98%) 65 (40.12%)
319+
320+
---
321+
322+
Code
323+
case2
324+
Output
325+
A: Drug X B: Placebo C: Combination
326+
(N=69) (N=73) (N=58)
327+
———————————————————————————————————————————————
328+
Y 80 (115.94%) 69 (94.52%) 65 (112.07%)
329+
330+
---
331+
332+
Code
333+
case3
334+
Output
335+
A: Drug X B: Placebo C: Combination
336+
(N=69) (N=73) (N=58)
337+
——————————————————————————————————————————————
338+
Y 80 (14.79%) 69 (12.75%) 65 (12.01%)
339+
340+
---
341+
342+
Code
343+
case4
344+
Output
345+
A: Drug X B: Placebo C: Combination
346+
(N=69) (N=73) (N=58)
347+
——————————————————————————————————————————————
348+
Y 80 (39.60%) 69 (38.98%) 65 (40.12%)
349+

tests/testthat/test-count_values.R

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,46 @@ testthat::test_that("count_values works as expected with multiple values and var
117117
res <- testthat::expect_silent(result)
118118
testthat::expect_snapshot(res)
119119
})
120+
121+
testthat::test_that("count_values works with denom specified", {
122+
result <- basic_table() %>%
123+
count_values("Species", values = "setosa", denom = "N_col") %>%
124+
build_table(iris)
125+
126+
res <- testthat::expect_silent(result)
127+
testthat::expect_snapshot(res)
128+
129+
# Some more test cases
130+
case1 <- testthat::expect_silent(
131+
basic_table(show_colcounts = TRUE) %>%
132+
split_cols_by("ACTARM") %>%
133+
count_values("AESER", values = "Y") %>%
134+
build_table(df = tern_ex_adae)
135+
)
136+
testthat::expect_snapshot(case1)
137+
138+
case2 <- testthat::expect_silent(
139+
basic_table(show_colcounts = TRUE) %>%
140+
split_cols_by("ACTARM") %>%
141+
count_values("AESER", values = "Y", denom = "N_col") %>%
142+
build_table(df = tern_ex_adae, alt_counts_df = tern_ex_adsl)
143+
)
144+
testthat::expect_snapshot(case2)
145+
146+
case3 <- testthat::expect_silent(
147+
basic_table(show_colcounts = TRUE) %>%
148+
split_cols_by("ACTARM") %>%
149+
count_values("AESER", values = "Y", denom = "N_row") %>%
150+
build_table(df = tern_ex_adae, alt_counts_df = tern_ex_adsl)
151+
)
152+
testthat::expect_snapshot(case3)
153+
154+
# case 4 should be the same as case 1 for the rows
155+
case4 <- testthat::expect_silent(
156+
basic_table(show_colcounts = TRUE) %>%
157+
split_cols_by("ACTARM") %>%
158+
count_values("AESER", values = "Y", denom = "n") %>%
159+
build_table(df = tern_ex_adae, alt_counts_df = tern_ex_adsl)
160+
)
161+
testthat::expect_snapshot(case4)
162+
})

0 commit comments

Comments
 (0)