| Title: | Create Common Tables and Listings Used in Clinical Trials |
| Version: | 0.1.7 |
| Date: | 2026-10-09 |
| Description: | Structure and formatting requirements for clinical trial table and listing outputs vary between pharmaceutical companies. 'junco' provides additional tooling for use alongside the 'rtables', 'rlistings' and 'tern' packages when creating table and listing outputs. While motivated by the specifics of Johnson and Johnson Clinical and Statistical Programming's table and listing shells, 'junco' provides functionality that is general and reusable. Major features include a) alternative and extended statistical analyses beyond what 'tern' supports for use in standard safety and efficacy tables, b) a robust production-grade Rich Text Format (RTF) and DOCX exporter for tables, listings and graphs, c) structural support for spanning column headers and risk difference columns in tables, and d) robust font-aware automatic column width algorithms for both listings and tables. |
| License: | Apache License (≥ 2) |
| URL: | https://github.com/johnsonandjohnson/junco, https://johnsonandjohnson.github.io/junco/ |
| BugReports: | https://github.com/johnsonandjohnson/junco/issues |
| Depends: | R (≥ 4.4), formatters (≥ 0.5.13), rtables (≥ 0.6.17) |
| Imports: | tidytlg (≥ 0.12.0), tern (≥ 0.9.13), rlistings (≥ 0.2.13), checkmate (≥ 2.1.0), rbmi (≥ 1.6.0), broom, methods, generics, stats, survival, tibble, utils, emmeans, mmrm, vcdExtra (≥ 0.8.7), rtables.officer (≥ 0.1.2), flextable (≥ 0.9.11), officer, xml2, ggplot2, assertthat |
| Encoding: | UTF-8 |
| Language: | en-US |
| Suggests: | knitr, rmarkdown, forcats (≥ 1.0.0), testthat (≥ 3.0.0), mockery, mvtnorm, parallel, readxl, rlang, tidyr, pharmaverseadamjnj (≥ 0.0.5), multcomp, lifecycle, dplyr, ratesci (≥ 1.1.0), random.cdisc.data |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| Config/roxygen2/version: | 8.1.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-10-12 22:45:58 UTC; gbecker |
| Author: | Gabriel Becker [cre, aut] (Original creator of the package, and author of included rtables functions), Ilse Augustyns [aut], Paul Jenkins [aut], Daniel Hofstaedter [aut], Joseph Kovach [aut], David Munoz Tord [aut], Daniel Sabanes Bove [aut], Ezequiel Anokian [ctb], Renfei Mao [ctb], Mrinal Das [ctb], Wojciech Wójciak [ctb], Johnson & Johnson Innovative Medicine [cph, fnd] |
| Maintainer: | Gabriel Becker <gabembecker@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-13 16:10:09 UTC |
Custom unlist function
Description
Unlist a list, but retain NULL as 'NULL' or NA.
Usage
.unlist_keep_nulls(lst, null_placeholder = "NULL", recursive = FALSE)
Combined Proportion, Risk Difference, and Risk Difference Test Analysis Function with Method Selection Based on the Mantel-Fleiss Criterion
Description
Performs a combined analysis of proportions, treatment-vs-control risk differences, and tests of risk differences.
The method used for the risk difference and risk difference test is selected based on the Mantel-Fleiss criterion. If the Mantel-Fleiss (MF) criterion is satisfied, the Cochran-Mantel-Haenszel (CMH) method with Sato variance is used for both the risk difference and the corresponding statistical test.
If the Mantel-Fleiss criterion is not satisfied, an exact method is used. Specifically, the exact unconditional method is used for estimation of the risk difference, and Fisher's exact test is used for the hypothesis test.
Usage
a_combo_prop_diff_pval_mf(
df,
.var,
.df_row,
.spl_context,
val,
colpaths,
id = "USUBJID",
trt_var,
ctrl_group,
variables = list(strata = NULL),
mf_threshold = NULL,
conf_level = 0.95,
alternative = c("two.sided", "less", "greater"),
exact_footnote = rtables::RefFootnote("Exact Inference", 1L, "+"),
.stats = NULL,
.formats = NULL,
...
)
Arguments
df |
( |
.var |
( |
.df_row |
( |
.spl_context |
( |
val |
( |
colpaths |
( |
id |
( |
trt_var |
( |
ctrl_group |
( |
variables |
( |
mf_threshold |
( |
conf_level |
( |
alternative |
( |
exact_footnote |
( |
.stats |
( If a statistic is not supplied for any of the three analysis types, the following defaults are used:
|
.formats |
( |
... |
Additional arguments reserved for compatibility with the rtables analysis function interface. |
Details
The analysis function determines which type of result to calculate based
on the current column path specified by colpaths.
-
"prop": calculates and displays the proportion for the current analysis facet. -
"diff": calculates the treatment-vs-control proportion difference. -
"pval": calculates the treatment-vs-control p-value.
For proportion columns, a_freq_j() is used. For risk difference and
p-value columns, the control group is identified from .df_row using
trt_var and ctrl_group, and the corresponding a_proportion_diff_mf()
or a_test_proportion_diff_mf() function is called.
The current column is identified using in_column() against each element
of colpaths list.
If the current column does not correspond to any of the configured prop,
diff, or pval paths, an empty rtables::rcell().
The function first determines the current row label from .spl_context.
If the current split represents the root of the analysis, the label
"Full analysis set" is used; otherwise, the value of the leaf split is
used.
Value
Returns the corresponding CellValue or RowsVerticalSection object with
formatted results.
Author(s)
WW
See Also
a_freq_j(), a_proportion_diff_mf(), a_test_proportion_diff_mf(),
Examples
library(dplyr)
adrs_f <- formatters::ex_adrs |>
filter(
ARM %in% c("A: Drug X", "B: Placebo"),
PARAMCD == "BESRSPI"
) |>
droplevels() |>
mutate(
rsp = factor(ifelse(AVALC == "CR", "Y", "N")),
ARM_FOR_RISKCOLS = ARM # Required for Risk Difference and p-value columns
)
riskcols_combodf <- tribble(
~valname, ~label, ~levelcombo, ~exargs,
"diff", "Risk Difference", "A: Drug X", list(),
"pval", "p-value", "B: Placebo", list()
)
col_split_fun <- add_combo_levels(
riskcols_combodf,
keep_levels = riskcols_combodf$valname
)
# Additional arguments for a_combo_prop_diff_pval_mf().
extra_args <- list(
colpaths = list(
prop = c("ARM", "*"),
diff = c("ARM_FOR_RISKCOLS", "diff"),
pval = c("ARM_FOR_RISKCOLS", "pval")
),
id = "SUBJID",
trt_var = "ARM",
ctrl_group = "B: Placebo",
val = "Y",
variables = list(strata = "BMRKR2"),
.stats = list(diff = "diff")
)
lyt <- basic_table(top_level_section_div = " ") |>
split_cols_by("ARM") |>
split_cols_by(
"ARM_FOR_RISKCOLS",
split_fun = col_split_fun,
nested = FALSE
) |>
analyze(
"rsp",
afun = a_combo_prop_diff_pval_mf,
extra_args = extra_args
) |>
split_rows_by(
var = "SEX",
split_label = "Gender",
child_labels = "hidden",
label_pos = "visible"
) |>
analyze(
vars = "rsp",
afun = a_combo_prop_diff_pval_mf,
extra_args = extra_args,
show_labels = "hidden"
)
tbl <- build_table(lyt, adrs_f)
tbl
Conditional proportion with adaptive CI (exact vs. Wald)
Description
Usage
a_cond_proportion_j(
df,
.var,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL,
.df_row = NULL
)
s_cond_proportion_j(
df,
.var,
conf_level = 0.95,
long = FALSE,
na.rm = FALSE,
num_limit = 0,
denom_limit = 10,
denom = c("n", "N_row"),
method_scope = c("cell", "row"),
.df_row = NULL
)
d_cond_proportion_j(
conf_level,
long = FALSE,
num_limit = NULL,
denom_limit = NULL,
method = NULL,
method_denom = NULL,
method_rsp = NULL
)
Arguments
df |
( |
.var |
( |
... |
additional arguments for the lower level functions. |
.stats |
( |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
.df_row |
( |
conf_level |
( |
long |
( |
na.rm |
( |
num_limit |
( |
denom_limit |
( |
denom |
( |
method_scope |
( |
method |
( |
method_denom |
( |
method_rsp |
( |
Details
The analysis function a_cond_proportion_j() is used to create a layout
element that estimates a response proportion with confidence interval,
automatically selecting between exact and Wald methods based on observed
counts and user-defined limits.
The statistics function mirrors tern::s_proportion() usage and output but
removes the method argument and decides internally between
"clopper-pearson" and "wald".
The exact method is used when any of these are true:
(a) the number of responders is num_limit (or less),
(b) all subjects except num_limit (or less) have observed response,
or (c) the observed group size is less than denom_limit.
Depending on the method_scope choice, this decision is either taken
based on the response data for an individual cell (method_scope = "cell"),
or based on the response data for the entire row (method_scope = "row"):
With
method_scope = "cell", the counts used for the decision are:numerator: the number of responders in the current cell;
denominator: the total number of observations in the cell (using
df) ifdenom = "n", or across the row (using.df_row) ifdenom = "N_row".
With
method_scope = "row", the counts used for the decision are:numerator: the total number of responders across the row (using
.df_row);denominator: the total number of observations across the row (from
.df_row).
CI computation follows tern::s_proportion() conventions: helper functions
are called with n = denom, so when denom = "N_row", this row-level
denominator is used for the interval.
Value
-
a_cond_proportion_j()returns the corresponding list with formattedrtables::CellValue().
-
s_cond_proportion_j()returns statisticsn_prop(nresponders and proportion) andprop_ci(proportion CI), formatted consistently withtern::s_proportion().
-
d_cond_proportion_j()returns a string describing the analysis label.
Functions
-
a_cond_proportion_j(): Formatted analysis function which is used asafunfor conditional proportion with adaptive CI selection (exact vs. Wald). -
s_cond_proportion_j(): Statistics function estimating a proportion along with its confidence interval, with adaptive method selection. -
d_cond_proportion_j(): Description helper function for the conditional proportion summary label.
Examples
nex <- 100
dta <- data.frame(
"rsp" = sample(c(TRUE, FALSE), nex, TRUE),
"grp" = sample(c("A", "B"), nex, TRUE),
"f1" = sample(c("a1", "a2"), nex, TRUE),
stringsAsFactors = TRUE
)
l <- basic_table() |>
split_cols_by(var = "grp") |>
analyze(
vars = "rsp",
afun = a_cond_proportion_j,
extra_args = list(
conf_level = 0.90,
num_limit = 0,
denom_limit = 10
)
)
build_table(l, df = dta)
# Logical vector input
rsp_v <- c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE)
s_cond_proportion_j(rsp_v)
# Data frame input
dta <- data.frame(rsp = c(TRUE, TRUE, FALSE, TRUE, FALSE, NA))
s_cond_proportion_j(dta, .var = "rsp", na.rm = TRUE)
# Using method_scope = "row" (requires .df_row in ...)
df_row <- data.frame(rsp = rep(rsp_v, 2))
s_cond_proportion_j(
dta, .var = "rsp", method_scope = "row",
.df_row = df_row, na.rm = TRUE
)
d_cond_proportion_j(conf_level = 0.90, long = FALSE, num_limit = 0, denom_limit = 10)
# With dedicated row-wise method:
d_cond_proportion_j(
conf_level = 0.90, long = TRUE, num_limit = 0, denom_limit = 10,
method = "wald", method_denom = 10, method_rsp = 8)
a_coxph_hr
Description
a_coxph_hr Use
tern:::a_coxph_pairwise()
instead, and usetern::coxph_pairwise()' as
the layout-level wrapper.
Usage
a_coxph_hr(
df,
.var,
ref_path,
.spl_context,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
Arguments
df |
( |
.var |
( |
ref_path |
( |
.spl_context |
( |
... |
Additional arguments passed to the statistics function. |
.stats |
( |
.formats |
( |
.labels |
( |
.indent_mods |
( |
Exposure-Adjusted Incidence Rate
Description
Statistical/Analysis Function for presenting Exposure-Adjusted Incidence Rate summary data
Usage
s_eair100_levii_j(
levii,
df,
.df_row,
.var,
.alt_df_full = NULL,
id = "USUBJID",
fup_var,
occ_var,
occ_dy,
num_p_year = 100,
count_multiple_events = FALSE,
conf_level = 0.95,
conf_type_diff = c("wald", "waldcc", "mn", "scas"),
conf_type_eair = c("exact", "normal", "normal_log", "byar"),
vs_ref_group = FALSE,
.in_ref_col,
cur_col_expr,
ref_col_expr,
inriskdiffcol = FALSE
)
a_eair100_j(
df,
labelstr = NULL,
.var,
.df_row,
.spl_context,
.alt_df_full = NULL,
id = "USUBJID",
fup_var,
occ_var,
occ_dy = NULL,
num_p_year = 100,
count_multiple_events = FALSE,
drop_levels = FALSE,
riskdiff = TRUE,
ref_path = NULL,
.stats = c("eair"),
.formats = NULL,
.labels = NULL,
.indent_mods = NULL,
na_str = rep("NA", 3),
conf_level = 0.95,
conf_type_diff = c("wald", "waldcc", "mn", "scas"),
conf_type_eair = c("normal", "normal_log", "exact", "byar"),
row_labels_adj = FALSE,
riskdiff_setup = c("horizontal", "vertical")
)
Arguments
levii |
( |
df |
( |
.df_row |
( |
.var |
( |
.alt_df_full |
( |
id |
( |
fup_var |
( |
occ_var |
( |
occ_dy |
( |
num_p_year |
( |
count_multiple_events |
( |
conf_level |
( |
conf_type_diff |
( |
conf_type_eair |
( |
vs_ref_group |
( |
cur_col_expr |
( |
ref_col_expr |
( |
inriskdiffcol |
( |
labelstr |
( |
.spl_context |
( |
drop_levels |
( |
riskdiff |
( |
ref_path |
( |
.stats |
( |
.formats |
(named 'character' or 'list') |
.labels |
(named 'character') |
.indent_mods |
(named |
na_str |
( |
row_labels_adj |
( |
riskdiff_setup |
( |
Details
The exposure-adjusted incidence rate (EAIR) is defined as:
When (
occ_varnotNULL) orcount_multiple_events = FALSE:
the number of subjects with at least one occurrence of a specified adverse event divided by the total at-risk exposure time across all subjects.When
occ_var = NULLandcount_multiple_events = TRUE:
the total number of events across of a specified adverse event divided by the total at-risk exposure time across all subjects.
Total at-risk exposure time is calculated for each subject as:
When
occ_varnotNULLfor subjects with the event: relative day (from the start of exposure) of the onset date of the first occurrence of the specified event (
occ_varandocc_dy), transformed from days into years asocc_dy/365.25, orfor subjects without the event: total duration of follow-up (expressed in years) (e.g., treatment discontinuation, completion, or censoring) (
fup_var).
When
occ_var = NULL
for all subjects: total duration of follow-up (expressed in years) (e.g., treatment discontinuation, completion, or censoring) (fup_var).
The EAIR is expressed as:
\mathrm{EAIR} = \hat r = \frac{n}{T}
where:
-
nis the number of subjects with at least one occurrence of the event T =
\sum_{i=1}^{N} t_i, with-
t_iis the at-risk exposure time for subjecti, expressed in subject-years
The difference between two EAIRs is
\hat \theta = (\hat r_1 - \hat r_2).
Wald's method for the confidence interval approximation is used (Liu et al., 2006), which uses the standard error
\mathrm{se}(\hat r_1 - \hat r_2) =
\sqrt{\frac{n_1}{T_1^2} + \frac{n_2}{T_2^2}}
and the 100(1-\alpha)\% confidence interval is
(\hat r_1 - \hat r_2) \pm z_{1-\alpha/2}\,\mathrm{se}(\hat r_1 - \hat r_2)
where z_{1-\alpha/2} is the standard normal quantile. 1
Other methods for confidence interval for difference can be specified in conf_type_diff argument.
EAIR is commonly reported per 100 subject-years:
\mathrm{EAIR}_{100} = 100 \times \hat r
Value
-
s_eair100_levii_j()returns a list containing the following statistics:n_event: Number of subjects with the event, or total event count if
count_multiple_events = TRUEperson_years: Total person-years of follow-up
eair: Exposure-adjusted incidence rate per
num_p_yearperson-yearsn_eair: Combination of
n_eventandeairstatistics.eair_n: Combination of
eairandn_eventstatistics.eair_n_py: Combination of
eair,n_eventandperson_yearsstatistics.eair_ci: Confidence interval for
eair, method specified inconf_type_eair.eair_est_ci: Combination of
eairandeair_ci.eair_diff_est: Difference in EAIR between current group and reference group (if
diff=TRUE andinriskdiffcol=TRUE)eair_diff_ci: Confidence interval for difference in EAIR between current group and reference group (if
diff=TRUE andinriskdiffcol=TRUE)eair_diff_est_ci: Combination of
eair_diff_estandeair_diff_ci.
The list of available statistics (core columns) can also be viewed by running
junco_get_stats("a_eair100_j").
-
a_eair100_jreturns the corresponding list with formattedrtables::CellValue().
Within a risk difference column, the statisticseairandn_eairare replaced byeair_diff_est_ci(difference in EAIR between current group and reference group, together with it's confidence interval).
Functions
-
s_eair100_levii_j(): calculates exposure-adjusted incidence rates (EAIR) pernum_p_yearperson-years for a specific level of a variable. -
a_eair100_j(): Formatted analysis function for exposure adjusted incidence rate summary which is used asafuninanalyzeorcfuninsummarize_row_groups.
References
Liu, G. F., Wang, J., Liu, K., and Snavely, D. B. (2006). Confidence intervals for an exposure adjusted incidence rate difference with applications to clinical trials. Statistics in Medicine, 25(8), 1275–1286. doi:10.1002/sim.2335
Examples
library(tern)
library(dplyr)
trtvar <- "ARM"
ctrl_grp <- "B: Placebo"
cutoffd <- as.Date("2023-09-24")
adexsum <- ex_adsl |>
create_colspan_var(
non_active_grp = ctrl_grp,
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = trtvar
) |>
mutate(
rrisk_header = "Risk Difference (95% CI)",
rrisk_label = paste(!!rlang::sym(trtvar), "vs", ctrl_grp),
TRTDURY = case_when(
!is.na(EOSDY) ~ EOSDY,
TRUE ~ as.integer(cutoffd - as.Date(TRTSDTM) + 1)
)
) |>
select(USUBJID, !!rlang::sym(trtvar), colspan_trt, rrisk_header, rrisk_label, TRTDURY)
adexsum$TRTDURY <- as.numeric(adexsum$TRTDURY)
adae <- ex_adae |>
group_by(USUBJID, AEDECOD) |>
select(USUBJID, AEDECOD, ASTDY) |>
mutate(rwnum = row_number()) |>
mutate(AOCCPFL = case_when(
rwnum == 1 ~ "Y",
TRUE ~ NA
)) |>
filter(AOCCPFL == "Y")
aefup <- left_join(adae, adexsum, by = "USUBJID")
colspan_trt_map <- create_colspan_map(adexsum,
non_active_grp = ctrl_grp,
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = trtvar
)
ref_path <- c("colspan_trt", " ", trtvar, ctrl_grp)
################################################################################
# Define layout and build table:
################################################################################
lyt <- basic_table(show_colcounts = TRUE, colcount_format = "N=xx", top_level_section_div = " ") |>
split_cols_by("colspan_trt", split_fun = trim_levels_to_map(map = colspan_trt_map)) |>
split_cols_by(trtvar) |>
split_cols_by("rrisk_header", nested = FALSE) |>
split_cols_by(trtvar, labels_var = "rrisk_label", split_fun = remove_split_levels(ctrl_grp)) |>
analyze("TRTDURY",
show_labels = "hidden",
afun = a_patyrs_j
) |>
analyze(
vars = "AEDECOD",
afun = a_eair100_j,
extra_args = list(
fup_var = "TRTDURY",
occ_var = "AOCCPFL",
occ_dy = "ASTDY",
ref_path = ref_path,
drop_levels = TRUE
)
)
result <- build_table(lyt, aefup, alt_counts_df = adexsum)
head(result, 5)
Stratified Exposure-Adjusted Incidence Rate (EAIR)
Description
Statistical/Analysis function for presenting a stratified exposure-adjusted incidence rate (EAIR) and its Wald confidence interval across strata (e.g., study size weighted exposure).
This function is an extension to the unstratified function a_eair100_j().
Usage
s_eair_strat_levii_j(
levii,
df,
.df_row,
.alt_df_full,
.var,
strata,
id = "USUBJID",
fup_var,
occ_var = NULL,
occ_dy = NULL,
num_p_year = 100,
count_multiple_events = FALSE,
conf_level = 0.95,
vs_ref_group = FALSE,
.in_ref_col,
cur_col_expr,
ref_col_expr,
inriskdiffcol = FALSE
)
a_eair_strat_j(
df,
labelstr = NULL,
.var,
.df_row,
.spl_context,
.alt_df_full = NULL,
id = "USUBJID",
strata,
fup_var,
occ_var = NULL,
occ_dy = NULL,
num_p_year = 100,
count_multiple_events = FALSE,
drop_levels = FALSE,
riskdiff = FALSE,
ref_path = NULL,
conf_level = 0.95,
.stats = "eair_strat",
.formats = NULL,
.labels = NULL,
.indent_mods = NULL,
na_str = rep("NA", 3),
row_labels_adj = FALSE,
riskdiff_setup = c("horizontal", "vertical")
)
Arguments
levii |
( |
df |
( |
.df_row |
( |
.alt_df_full |
( |
.var |
( |
strata |
( |
id |
( |
fup_var |
( |
occ_var |
( |
occ_dy |
( |
num_p_year |
( |
count_multiple_events |
( |
conf_level |
( |
vs_ref_group |
( |
cur_col_expr |
( |
ref_col_expr |
( |
inriskdiffcol |
( |
labelstr |
( |
.spl_context |
( |
drop_levels |
( |
riskdiff |
( |
ref_path |
( |
.stats |
( |
.formats |
(named 'character' or 'list') |
.labels |
(named 'character') |
.indent_mods |
(named |
na_str |
( |
row_labels_adj |
( |
riskdiff_setup |
( |
Details
The weighting method uses raw event counts n_ti in both the rate and variance.
\hat r_{ti} = \texttt{num\_p\_year} \times \frac{n_{ti}}{T_{ti}}
The strata weight is w_i = T_0i + T_1i (total person-years across
all groups in strata i), and the pooled weighted rate is:
\hat r_t = \sum_i \frac{w_i}{W} \hat r_{ti}, \quad W = \sum_i w_i
The Wald 95% CI for the pooled rate is:
\hat r_t \pm z_{1-\alpha/2} \times \frac{\texttt{num\_p\_year}}{W}
\sqrt{\sum_i w_i^2 \frac{n_{ti}}{T_{ti}^2}}
.
The weighted rate difference and its Wald CI are:
\hat\delta = \sum_i \frac{w_i}{W}(\hat r_{1i} - \hat r_{0i})
\hat\delta \pm z_{1-\alpha/2} \times \frac{\texttt{num\_p\_year}}{W}
\sqrt{\sum_i w_i^2 \left(\frac{n_{1i}+c}{T_{1i}^2} + \frac{n_{0i}}{T_{0i}^2}\right)}
Value
-
s_eair_strat_levii_j()returns a list containing the following statistics:
-
n_event_total: total event count across strata (current arm) -
person_years_total: total person-years across strata (current arm) -
eair_strat: stratified pooled EAIR pernum_p_yearperson-years -
n_eair_strat: composite ofn_event_totalandeair_strat -
eair_strat_ci: Wald CI foreair_strat -
eair_strat_est_ci: composite ofeair_stratandeair_strat_ci -
eair_strat_n: composite ofeair_stratandn_event_total -
eair_strat_n_py: composite ofeair_strat,n_event_totalandperson_years_total -
eair_strat_diff_est_ci: stratified rate difference with Wald CI (only whenvs_ref_group = TRUE, otherwiseNULL) -
eair_strat_diff_est: estimate for the difference in stratified rate -
eair_strat_diff_ci: CI (Wald type) for the difference in stratified rate
The list of available statistics (core columns) can also be viewed by
running junco_get_stats("a_eair_strat_j").
-
a_eair_strat_j()returns a list of formattedrtables::CellValue()rows. Within a risk difference column, the statisticseair_stratandn_eair_stratare replaced byeair_strat_diff_est_ci(difference in EAIR between current group and reference group, together with it's confidence interval).
Functions
-
a_eair_strat_j(): Formatted analysis function for stratified (eg study size-weighted) EAIR, used asafuninrtables::analyze().
References
Scosyrev, E & Pethe, A (2022). Confidence intervals for exposure-adjusted rate differences in randomized trials. Pharmaceutical Statistics, 2022;21:103–121. doi: 10.1002/pst.2155
Crowe, B., Chuang-Stein, C., Lettis, S., & Brueckner, A. (2016). Reporting adverse drug reactions in product labels. Therapeutic Innovation & Regulatory Science, 50(4), 455-463. doi: 10.1177/2168479016628574
See Also
Examples
library(tern)
library(dplyr)
set.seed(42)
n <- 120
adsl <- data.frame(
USUBJID = paste0("S", seq_len(n)),
ARM = rep(c("Treatment", "Placebo"), each = n / 2),
STUDY = rep(c("Study1", "Study2", "Study3"), times = n / 3),
TRTDURY = runif(n, 0.5, 3),
stringsAsFactors = FALSE
)
adae <- data.frame(
USUBJID = sample(adsl$USUBJID, 40),
AEDECOD = "Headache",
ASTDY = sample(30:500, 40, replace = TRUE),
AOCCPFL = "Y",
stringsAsFactors = FALSE
)
aefup <- merge(adae, adsl, by = "USUBJID")
# Standard method (matches rdcomaeinci SAS macro)
lyt <- basic_table() |>
split_cols_by("ARM") |>
analyze(
"AEDECOD",
afun = a_eair_strat_j,
extra_args = list(
strata = "STUDY",
fup_var = "TRTDURY",
occ_var = "AOCCPFL",
occ_dy = "ASTDY",
.stats = c("eair_strat", "eair_strat_ci")
)
)
result <- build_table(lyt, aefup, alt_counts_df = adsl)
result
Analysis function count and percentage in column design controlled by combosdf
Description
Analysis function count and percentage in column design controlled by combosdf
Usage
a_freq_combos_j(
df,
labelstr = NULL,
.var = NA,
val = NULL,
combosdf = NULL,
do_not_filter = NULL,
filter_var = NULL,
flag_var = NULL,
.df_row,
.spl_context,
.N_col,
id = "USUBJID",
denom = c("N_col", "n_df", "n_altdf", "n_rowdf", "n_parentdf"),
label = NULL,
label_fstr = NULL,
label_map = NULL,
.alt_df_full = NULL,
denom_by = NULL,
.stats = "count_unique_denom_fraction",
.formats = NULL,
.labels_n = NULL,
.indent_mods = NULL,
na_str = rep("NA", 3)
)
Arguments
df |
( |
labelstr |
( |
.var |
( |
val |
( |
combosdf |
The df which provides the mapping of column facets to produce cumulative counts for .N_col. |
do_not_filter |
A vector of facets (i.e., column headers), identifying headers for which no filtering of records should occur. That is, the numerator should contain cumulative counts. Generally, this will be used for a "Total" column, or something similar. |
filter_var |
The variable which identifies the records to count in the numerator for any given column. Generally, this will contain text matching the column header for the column associated with a given record. |
flag_var |
Variable which identifies the occurrence (or first occurrence) of an event. The flag variable is expected to have a value of "Y" identifying that the event should be counted, or NA otherwise. |
.df_row |
( |
.spl_context |
( |
.N_col |
( |
id |
( |
denom |
(
|
label |
( |
label_fstr |
( |
label_map |
( Four types of mappings are supported:
Here, Recommendation: ensure input variable(s) are of type factor, to avoid the error
"got a label map that doesn't provide labels for all values". See examples for more details. |
.alt_df_full |
( |
denom_by |
( |
.stats |
( |
.formats |
(named 'character' or 'list') |
.labels_n |
(named |
.indent_mods |
(named |
na_str |
( |
Value
list of requested statistics with formatted rtables::CellValue().
See Also
a_freq_j() for extensive label_map usage examples.
Examples
library(dplyr)
ADSL <- ex_adsl |> select(USUBJID, ARM, EOSSTT, EOSDT, EOSDY, TRTSDTM)
cutoffd <- as.Date("2023-09-24")
ADSL <- ADSL |>
mutate(
TRTDURY = case_when(
!is.na(EOSDY) ~ EOSDY,
TRUE ~ as.integer(cutoffd - as.Date(TRTSDTM) + 1)
)
) |>
mutate(ACAT1 = case_when(
TRTDURY < 183 ~ "0-6 Months",
TRTDURY < 366 ~ "6-12 Months",
TRUE ~ "+12 Months"
)) |>
mutate(ACAT1 = factor(ACAT1, levels = c("0-6 Months", "6-12 Months", "+12 Months")))
ADAE <- ex_adae |> select(USUBJID, ARM, AEBODSYS, AEDECOD, ASTDY)
ADAE <- ADAE |>
mutate(TRTEMFL = "Y") |>
mutate(ACAT1 = case_when(
ASTDY < 183 ~ "0-6 Months",
ASTDY < 366 ~ "6-12 Months",
TRUE ~ "+12 Months"
)) |>
mutate(ACAT1 = factor(ACAT1, levels = c("0-6 Months", "6-12 Months", "+12 Months")))
combodf <- tribble(
~valname, ~label, ~levelcombo, ~exargs,
"Tot", "Total", c("0-6 Months", "6-12 Months", "+12 Months"), list(),
"A_0-6 Months", "0-6 Months", c("0-6 Months", "6-12 Months", "+12 Months"), list(),
"B_6-12 Months", "6-12 Months", c("6-12 Months", "+12 Months"), list(),
"C_+12 Months", "+12 Months", c("+12 Months"), list()
)
lyt <- basic_table(show_colcounts = TRUE) |>
split_cols_by("ARM") |>
split_cols_by("ACAT1",
split_fun = rtables::add_combo_levels(
combosdf = combodf,
trim = FALSE, keep_levels = combodf$valname
)
) |>
analyze("TRTEMFL",
show_labels = "hidden",
afun = a_freq_combos_j,
extra_args = list(
val = "Y",
label = "Subjects with >= 1 AE",
combosdf = combodf,
filter_var = "ACAT1",
do_not_filter = "Tot"
)
)
result <- build_table(lyt, df = ADAE, alt_counts_df = ADSL)
result
Analysis/statistical function for count and percentage in core columns and (optional) relative risk columns
Description
Analysis/statistical function for count and percentage in core columns and (optional) relative risk columns
Usage
s_freq_j(
df,
.var,
.df_row,
val = NULL,
drop_levels = FALSE,
excl_levels = NULL,
alt_df,
parent_df,
id = "USUBJID",
denom = c("n_df", "n_altdf", "N_col", "n_rowdf", "n_parentdf"),
.N_col,
countsource = c("df", "altdf", "altdf_subset")
)
a_freq_j(
df,
labelstr = NULL,
.var = NA,
val = NULL,
drop_levels = FALSE,
excl_levels = NULL,
new_levels = NULL,
new_levels_after = FALSE,
addstr2levs = NULL,
.df_row,
.spl_context,
.N_col,
id = "USUBJID",
denom = c("N_col", "n_df", "n_altdf", "N_colgroup", "n_rowdf", "n_parentdf"),
riskdiff = TRUE,
ref_path = NULL,
variables = list(strata = NULL),
conf_level = 0.95,
method = c("wald", "waldcc", "cmh", "ha", "newcombe", "newcombecc", "strat_newcombe",
"strat_newcombecc", "cmh_sato", "cmh_mn", "uncond_exact_diff"),
weights_method = "cmh",
label = NULL,
label_fstr = NULL,
label_map = NULL,
.alt_df_full = NULL,
denom_by = NULL,
.stats = "count_unique_denom_fraction",
.formats = NULL,
.indent_mods = NULL,
na_str = rep("NA", 3),
.labels_n = NULL,
extrablankline = FALSE,
extrablanklineafter = NULL,
restr_columns = NULL,
colgroup = NULL,
countsource = c("df", "altdf", "altdf_subset")
)
a_freq_j_with_exclude(
df,
labelstr = NULL,
exclude_levels,
.var = NA,
.spl_context,
.df_row,
.N_col,
.alt_df_full = NULL,
.stats = "count_unique_denom_fraction",
.formats = NULL,
.indent_mods = NULL,
.labels_n = NULL,
...
)
Arguments
df |
( |
.var |
( |
.df_row |
( |
val |
( |
drop_levels |
( |
excl_levels |
( |
alt_df |
( |
parent_df |
( |
id |
( |
denom |
( |
.N_col |
( |
countsource |
Either |
labelstr |
An argument to ensure this function can be used
as a |
new_levels |
(list(2) or NULL) |
new_levels_after |
( |
addstr2levs |
string, if not NULL will be appended to the rowlabel for that level, eg to add ",n (percent)" at the end of the rowlabels |
.spl_context |
( |
riskdiff |
( |
ref_path |
( |
variables |
Will be passed onto the risk difference function
(internal function s_risk_diff_val_j), which is based upon |
conf_level |
( |
method |
Will be passed onto the risk difference function (internal function s_risk_diff_val_j). |
weights_method |
Will be passed onto the risk difference function (internal function s_risk_diff_val_j). |
label |
( |
label_fstr |
( |
label_map |
( Four types of mappings are supported:
Here, Recommendation: ensure input variable(s) are of type factor, to avoid the error
"got a label map that doesn't provide labels for all values". See examples for more details. |
.alt_df_full |
( |
denom_by |
( |
.stats |
( |
.formats |
(named 'character' or 'list') |
.indent_mods |
(named |
na_str |
( |
.labels_n |
(named |
extrablankline |
( |
extrablanklineafter |
( |
restr_columns |
|
colgroup |
The name of the column group variable that is used as source
for denominator calculation. |
exclude_levels |
( |
... |
additional arguments for the lower level functions. |
Details
denom controls the denominator used to calculate proportions/percents.
It must be one of
-
N_col Column count,
-
n_df Number of patients (based upon the main input dataframe
df),
-
n_altdf Number of patients from the secondary dataframe (
.alt_df_full),
Note that argumentdenom_bywill perform a row-split on the.alt_df_fulldataframe.
It is a requirement that variables specified indenom_byare part of the row split specifications.
-
N_colgroup Number of patients from the column group variable (note that this is based upon the input .alt_df_full dataframe).
Note that the argumentcolgroup(column variable) needs to be provided, as it cannot be retrieved directly from the column layout definition. -
n_rowdf Number of patients from the current row-level dataframe (
.row_dffrom the rtables splitting machinery).
-
n_parentdf Number of patients from a higher row-level split than the current split.
This higher row-level split is specified in the argumentdenom_by.
Value
-
s_freq_j: returns a list of following statistics
n_df
n_rowdf
n_parentdf
n_altdf
denom
count
count_unique
count_unique_fraction
count_unique_denom_fraction
unique_fraction
-
a_freq_j: returns a list of requested statistics with formattedrtables::CellValue().
Within the relative risk difference columns, the following stats are blanked out:any of the n-statistics (n_df, n_altdf, n_parentdf, n_rowdf, denom)
count
count_unique
For the others (count_unique_fraction, count_unique_denom_fraction, unique_fraction), the statistic is replaced by the relative risk difference + confidence interval.
Functions
-
a_freq_j_with_exclude(): Wrapper for theafunwhich can exclude row split levels from producing the analysis. These have to be specified in theexclude_levelsargument, see?do_exclude_splitfor details.
Examples
library(dplyr)
adsl <- ex_adsl |> select("USUBJID", "SEX", "ARM")
adae <- ex_adae |> select("USUBJID", "AEBODSYS", "AEDECOD")
adae[["TRTEMFL"]] <- "Y"
trtvar <- "ARM"
ctrl_grp <- "B: Placebo"
adsl$colspan_trt <- factor(ifelse(adsl[[trtvar]] == ctrl_grp, " ", "Active Study Agent"),
levels = c("Active Study Agent", " ")
)
adsl$rrisk_header <- "Risk Difference (%) (95% CI)"
adsl$rrisk_label <- paste(adsl[[trtvar]], paste("vs", ctrl_grp))
adae <- adae |> left_join(adsl)
colspan_trt_map <- create_colspan_map(adsl,
non_active_grp = "B: Placebo",
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = trtvar
)
ref_path <- c("colspan_trt", " ", trtvar, ctrl_grp)
lyt <- basic_table(show_colcounts = TRUE) |>
split_cols_by("colspan_trt", split_fun = trim_levels_to_map(map = colspan_trt_map)) |>
split_cols_by(trtvar) |>
split_cols_by("rrisk_header", nested = FALSE) |>
split_cols_by(trtvar, labels_var = "rrisk_label", split_fun = remove_split_levels(ctrl_grp))
lyt1 <- lyt |>
analyze("TRTEMFL",
show_labels = "hidden",
afun = a_freq_j,
extra_args = list(
method = "wald",
.stats = c("count_unique_denom_fraction"),
ref_path = ref_path
)
)
result1 <- build_table(lyt1, adae, alt_counts_df = adsl)
result1
x_drug_x <- list(length(unique(subset(adae, adae[[trtvar]] == "A: Drug X")[["USUBJID"]])))
N_x_drug_x <- length(unique(subset(adsl, adsl[[trtvar]] == "A: Drug X")[["USUBJID"]]))
y_placebo <- list(length(unique(subset(adae, adae[[trtvar]] == ctrl_grp)[["USUBJID"]])))
N_y_placebo <- length(unique(subset(adsl, adsl[[trtvar]] == ctrl_grp)[["USUBJID"]]))
tern::stat_propdiff_ci(
x = x_drug_x,
N_x = N_x_drug_x,
y = y_placebo,
N_y = N_y_placebo
)
x_combo <- list(length(unique(subset(adae, adae[[trtvar]] == "C: Combination")[["USUBJID"]])))
N_x_combo <- length(unique(subset(adsl, adsl[[trtvar]] == "C: Combination")[["USUBJID"]]))
tern::stat_propdiff_ci(
x = x_combo,
N_x = N_x_combo,
y = y_placebo,
N_y = N_y_placebo
)
extra_args_rr <- list(
denom = "n_altdf",
denom_by = "SEX",
riskdiff = FALSE,
.stats = c("count_unique")
)
extra_args_rr2 <- list(
denom = "n_altdf",
denom_by = "SEX",
riskdiff = TRUE,
ref_path = ref_path,
method = "wald",
.stats = c("count_unique_denom_fraction"),
na_str = rep("NA", 3)
)
lyt2 <- basic_table(
top_level_section_div = " ",
colcount_format = "N=xx"
) |>
split_cols_by("colspan_trt", split_fun = trim_levels_to_map(map = colspan_trt_map)) |>
split_cols_by(trtvar, show_colcounts = TRUE) |>
split_cols_by("rrisk_header", nested = FALSE) |>
split_cols_by(trtvar,
labels_var = "rrisk_label", split_fun = remove_split_levels("B: Placebo"),
show_colcounts = FALSE
) |>
split_rows_by("SEX", split_fun = drop_split_levels) |>
summarize_row_groups("SEX",
cfun = a_freq_j,
extra_args = append(extra_args_rr, list(label_fstr = "Gender: %s"))
) |>
split_rows_by("TRTEMFL",
split_fun = keep_split_levels("Y"),
indent_mod = -1L,
section_div = c(" ")
) |>
summarize_row_groups("TRTEMFL",
cfun = a_freq_j,
extra_args = append(extra_args_rr2, list(
label =
"Subjects with >=1 AE", extrablankline = TRUE
))
) |>
split_rows_by("AEBODSYS",
split_label = "System Organ Class",
split_fun = trim_levels_in_group("AEDECOD"),
label_pos = "topleft",
section_div = c(" "),
nested = TRUE
) |>
summarize_row_groups("AEBODSYS",
cfun = a_freq_j,
extra_args = extra_args_rr2
) |>
analyze("AEDECOD",
afun = a_freq_j,
extra_args = extra_args_rr2
)
result2 <- build_table(lyt2, adae, alt_counts_df = adsl)
# -------------------------------------------------------------------------
# Examples using the label_map argument
# -------------------------------------------------------------------------
adsl <- ex_adsl |> select("USUBJID", "SEX", "ARM")
adae <- ex_adae |> select("USUBJID", "AEBODSYS", "AEDECOD")
adae[["TRTEMFL"]] <- "Y"
trtvar <- "ARM"
adae <- adae |> left_join(adsl)
# -------------------------------------------------------------------------
# 1. Simple mapping.
# Remaps factor levels (value) to custom new labels (label).
# -------------------------------------------------------------------------
label_map_simple <- data.frame(
value = c("M", "F", "UNDIFFERENTIATED", "U"),
label = c("Male", "Female", "Undifferentiated", "Unknown")
)
lyt_lmap1 <- basic_table(show_colcounts = TRUE) |>
split_cols_by(trtvar) |>
analyze("SEX",
afun = a_freq_j,
extra_args = list(
.stats = "count_unique_fraction",
label_map = label_map_simple
)
)
result_lmap1 <- build_table(lyt_lmap1, adsl, alt_counts_df = adsl)
result_lmap1
# -------------------------------------------------------------------------
# 2. Multi-variable mapping.
# Useful in situations where multiple Y/N variables can be analyzed in one
# [rtables::analyze()] call.
# -------------------------------------------------------------------------
multi_vars <- c("DTH30FL", "DTHA30FL", "DTHB30FL")
adslx <- pharmaverseadamjnj::adsl
# ensure the variables are factor with levels Y/N - and variable label is kept
adslx <- adslx |>
mutate(across(all_of(multi_vars), \(x) structure(
factor(x, levels = c("Y", "N")),
label = attr(x, "label")
)))
map_multi <- data.frame(
var = multi_vars,
value = "Y",
label = c(
"Death <=30D of Last Trt Flag",
"Death >30D from Last Trt Flag",
"Death <=30D of First Trt Flag"
)
)
lyt_lmap1 <- basic_table(show_colcounts = TRUE) |>
split_cols_by("ARM") |>
analyze(multi_vars,
afun = a_freq_j,
extra_args = list(
.stats = "count_unique_denom_fraction",
label_map = map_multi,
val = "Y"
),
show_labels = "hidden"
)
result_lmap2 <- build_table(lyt_lmap1, adslx)
result_lmap2
# -------------------------------------------------------------------------
# 3. Conditional-on-row-split mapping.
# -------------------------------------------------------------------------
map_rowsplit <- data.frame(
SEX = c("M", "F"),
value = c("Y", "Y"),
label = c("Male subjects with >=1 TE AE", "Female subjects with >=1 TE AE")
)
adsl <- ex_adsl |> select("USUBJID", "ARM", "SEX")
adae <- ex_adae |> select("USUBJID", "AEBODSYS", "AEDECOD")
adae[["TRTEMFL"]] <- "Y"
adae <- adae |> left_join(adsl)
lyt_lmap3 <- basic_table(show_colcounts = TRUE) |>
split_cols_by("ARM") |>
split_rows_by("SEX", split_fun = keep_split_levels(c("F", "M")), child_labels = "hidden") |>
analyze("TRTEMFL",
afun = a_freq_j,
extra_args = list(
.stats = "count_unique_denom_fraction",
label_map = map_rowsplit,
val = "Y"
),
show_labels = "hidden"
)
result_lmap3 <- build_table(lyt_lmap3, adae, alt_counts_df = adsl)
result_lmap3
# -----------------------------------------------------------------------------------
# 4. Conditional-on-row-split multi-variable mapping.
# -----------------------------------------------------------------------------------
adsl_jnj <- pharmaverseadamjnj::adsl
advs_jnj <- pharmaverseadamjnj::advs
multi_vars <- c("CRIT1FL", "CRIT2FL", "CRIT3FL")
map_multi_rowsplit <- data.frame(
PARAMCD = c(rep("DIABP", 3), rep("SYSBP", 3)),
var = rep(multi_vars, 2),
value = rep("Y", 6),
label = c(
"<50 mmHg and with >20 mmHg decrease from baseline",
">105 mmHg and with >30 mmHg increase from baseline",
"Diastolic blood pressure<60",
"<90 mmHg and with >30 mmHg decrease from baseline",
">180 mmHg and with >40 mmHg increase from baseline",
"Systolic blood pressure<90"
)
)
lyt_lmap4 <- basic_table(show_colcounts = TRUE) |>
split_cols_by("TRT01A") |>
split_rows_by("PARAMCD", split_fun = keep_split_levels(c("DIABP", "SYSBP"))) |>
analyze(multi_vars,
afun = a_freq_j,
extra_args = list(
.stats = "count_unique_denom_fraction",
label_map = map_multi_rowsplit,
val = "Y"
),
show_labels = "hidden"
)
result_lmap4 <- build_table(lyt_lmap4, advs_jnj, alt_counts_df = adsl_jnj)
result_lmap4
Analysis Function for Response Variables
Description
This function calculates counts and percentages for response variables (Y/N values), with optional risk difference calculations.
Usage
a_freq_resp_var_j(
df,
.var,
.df_row,
.N_col,
.spl_context,
resp_var = NULL,
id = "USUBJID",
drop_levels = FALSE,
riskdiff = TRUE,
ref_path = NULL,
variables = list(strata = NULL),
conf_level = formals(s_proportion_diff)$conf_level,
method = c("wald", "waldcc", "cmh", "ha", "newcombe", "newcombecc", "strat_newcombe",
"strat_newcombecc", "cmh_sato", "cmh_mn", "uncond_exact_diff"),
weights_method = formals(s_proportion_diff)$weights_method,
.formats = NULL,
na_str = rep("NA", 3),
legacy = FALSE
)
Arguments
df |
( |
.var |
( |
.df_row |
( |
.N_col |
( |
.spl_context |
( |
resp_var |
( |
id |
( |
drop_levels |
( |
riskdiff |
( |
ref_path |
( |
variables |
( |
conf_level |
( |
method |
( |
weights_method |
( |
.formats |
( |
na_str |
( |
legacy |
( |
Value
Formatted analysis function which is used as afun in analyze_vars()
and as cfun in summarize_row_groups().
Examples
library(dplyr)
ADSL <- ex_adsl |> select(USUBJID, ARM, SEX)
ADAE <- ex_adae |> select(USUBJID, ARM, SEX, AEBODSYS, AEDECOD)
ADAE <- ADAE |>
mutate(TRTEMFL = "Y")
lyt <- basic_table(show_colcounts = TRUE) |>
split_cols_by("ARM") |>
analyze("SEX",
show_labels = "visible",
afun = a_freq_resp_var_j,
extra_args = list(resp_var = "TRTEMFL", riskdiff = FALSE)
)
result <- build_table(lyt, df = ADAE, alt_counts_df = ADSL)
result
Analysis function count and percentage with extra column-subsetting in selected columns (controlled by subcol_* arguments)
Description
Analysis function count and percentage with extra column-subsetting in selected columns (controlled by subcol_* arguments)
Usage
a_freq_subcol_j(
df,
labelstr = NULL,
.var = NA,
val = NULL,
subcol_split = NULL,
subcol_var = NULL,
subcol_val = NULL,
.df_row,
.spl_context,
.N_col,
id = "USUBJID",
denom = c("N_col", "n_df", "n_altdf", "n_rowdf", "n_parentdf"),
label = NULL,
label_fstr = NULL,
label_map = NULL,
.alt_df_full = NULL,
denom_by = NULL,
.stats = c("count_unique_denom_fraction"),
.formats = NULL,
.labels_n = NULL,
.indent_mods = NULL,
na_str = rep("NA", 3)
)
Arguments
df |
( |
labelstr |
( |
.var |
( |
val |
( |
subcol_split |
( |
subcol_var |
( |
subcol_val |
( |
.df_row |
( |
.spl_context |
( |
.N_col |
( |
id |
( |
denom |
(
|
label |
( |
label_fstr |
( |
label_map |
( Four types of mappings are supported:
Here, Recommendation: ensure input variable(s) are of type factor, to avoid the error
"got a label map that doesn't provide labels for all values". See examples for more details. |
.alt_df_full |
( |
denom_by |
( |
.stats |
( |
.formats |
(named 'character' or 'list') |
.labels_n |
(named |
.indent_mods |
(named |
na_str |
( |
Value
list of requested statistics with formatted rtables::CellValue().
See Also
a_freq_j() for extensive label_map usage examples.
Examples
library(dplyr)
ADSL <- ex_adsl |>
select(USUBJID, ARM)
ADSL$COLSPAN_REL <- "AEs"
ADAE <- ex_adae |>
select(USUBJID, ARM, AEDECOD, AREL)
ADAE <- ADAE |>
mutate(
AEREL = case_when(
AREL == "Y" ~ "RELATED",
AREL == "N" ~ "NOT RELATED"
),
AEREL = factor(AEREL),
COLSPAN_REL = "AEs"
)
combodf <- tribble(
~valname, ~label, ~levelcombo, ~exargs,
"RELATED", "Related AEs", c("AEs"), list()
)
lyt <- basic_table(show_colcounts = TRUE) |>
split_cols_by("COLSPAN_REL", split_fun = rtables::add_combo_levels(combodf, trim = TRUE)) |>
split_cols_by("ARM") |>
analyze("AEDECOD",
afun = a_freq_subcol_j,
extra_args = list(
subcol_split = "RELATED",
subcol_var = "AEREL",
subcol_val = "RELATED"
)
)
result <- build_table(lyt, ADAE, alt_counts_df = ADSL)
result
a_kaplan_meier
Description
Use
tern::a_surv_time() instead.
Usage
a_kaplan_meier(
df,
.var,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
Arguments
df |
( |
.var |
( |
... |
additional arguments (ignored). |
.stats |
( |
.formats |
( |
.labels |
( |
.indent_mods |
( |
Calculate Count and Percentage of the Maximum Level of an Ordered Factor per Subject.
Description
A formatted analysis function used as an afun in
analyze and as a cfun in summarize_row_groups.
It computes count and proportion statistics for the maximum level of an
ordered factor, df[[.var]], for each unique subject in df[[id]].
Specifically, for each subject, the function identifies the highest level
of df[[.var]], producing one value per subject.
Then, if any_level = TRUE, the function reports the total number of
maximum values, excluding those specified in any_level_exclude.
Otherwise, it tabulates the frequency of each maximum level across all
subjects.
This function is particularly useful for identifying the maximum severity of adverse events in a treatment sequence, where the most severe event experienced by a subject is used for reporting.
Usage
a_maxlev(
df,
labelstr = NULL,
.var,
.spl_context,
id = "USUBJID",
.alt_df_full = NULL,
any_level = FALSE,
any_level_exclude = "Missing",
...
)
Arguments
df |
( |
labelstr |
( |
.var |
( |
.spl_context |
( |
id |
( |
.alt_df_full |
( |
any_level |
( |
any_level_exclude |
( |
... |
additional arguments for the lower level functions. |
Details
For each unique subject, only the maximum level of the ordered factor
df[[.var]] is included in the final count and percentage statistics.
Value
A RowsVerticalSection object.
Note
The denominator for proportions is computed using the denom_df
argument. This serves as a temporary workaround until the next version of
rtables is released, which will support .alt_count_df for use in
afun/cfun.
Author(s)
WW
Examples
treatments <- factor(c("a", "b", "c"))
ae_severities <- c("Missing", "Mild", "Moderate", "Severe")
ae_severities <- ordered(ae_severities, levels = ae_severities)
my_adae <- data.frame(
ID = c(1, 1, 1, 2, 2, 3, 3, 3, 3, 4),
TRT = factor(c("a", "b", "b", "b", "c", "c", "a", "c", "b", "b")),
AESEV = ae_severities[c(4L, 1L, 2L, 1L, 2L, 1L, 2L, 3L, 1L, 2L)]
)
my_adsl <- data.frame(
ID = rep(1:5, each = 3),
TRT = factor(rep(c("a", "b", "c"), times = 5))
)
aesevall_spf <- make_combo_splitfun(
nm = "AESEV_ALL",
label = "Any AE",
levels = NULL,
)
lyt <- basic_table() |>
split_cols_by("TRT") |>
add_overall_col("Total") |>
split_rows_by("AESEV", split_fun = aesevall_spf) |>
summarize_row_groups(
"AESEV",
cfun = a_maxlev,
extra_args = list(id = "ID", any_level = TRUE)
) |>
analyze(
"AESEV",
afun = a_maxlev,
extra_args = list(id = "ID")
)
build_table(lyt, my_adae, alt_counts_df = my_adsl)
Patient years exposure
Description
Statistical/Analysis Function for presenting Patient years exposure summary data
Usage
s_patyrs_j(
df,
.var,
id = "USUBJID",
.alt_df_full,
source = c("alt_df", "df"),
inriskdiffcol = FALSE
)
a_patyrs_j(
df,
.var,
.df_row,
id = "USUBJID",
.alt_df_full = NULL,
.formats = NULL,
.labels = NULL,
source = c("alt_df", "df"),
.spl_context,
.stats = "patyrs"
)
Arguments
df |
( |
.var |
( |
id |
( |
.alt_df_full |
( |
source |
( |
inriskdiffcol |
( |
.df_row |
( |
.formats |
(named 'character' or 'list') |
.labels |
(named 'character') |
.spl_context |
( |
.stats |
( |
Value
-
s_patyrs_j()returns a list containing the patient years statistics. The list of available statistics for can be viewed by runningjunco_get_stats("a_patyrs_j"). Currently, this is just a single statisticpatyrs, patient years of exposure.
-
a_patyrs_jreturns the corresponding list with formattedrtables::CellValue().
Functions
-
s_patyrs_j(): Statistical Function for Patient years exposure summary data -
a_patyrs_j(): Formatted analysis function for patient years summary which is used asafuninanalyzeorcfuninsummarize_row_groups.
Examples
library(tern)
library(dplyr)
trtvar <- "ARM"
ctrl_grp <- "B: Placebo"
cutoffd <- as.Date("2023-09-24")
adexsum <- ex_adsl |>
create_colspan_var(
non_active_grp = ctrl_grp,
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = trtvar
) |>
mutate(
rrisk_header = "Risk Difference (95% CI)",
rrisk_label = paste(!!rlang::sym(trtvar), "vs", ctrl_grp),
TRTDURY = case_when(
!is.na(EOSDY) ~ EOSDY,
TRUE ~ as.integer(cutoffd - as.Date(TRTSDTM) + 1)
)
) |>
select(USUBJID, !!rlang::sym(trtvar), colspan_trt, rrisk_header, rrisk_label, TRTDURY)
adae <- ex_adae |>
group_by(USUBJID, AEDECOD) |>
select(USUBJID, AEDECOD, ASTDY) |>
mutate(rwnum = row_number()) |>
mutate(AOCCPFL = case_when(
rwnum == 1 ~ "Y",
TRUE ~ NA
)) |>
filter(AOCCPFL == "Y")
aefup <- left_join(adae, adexsum, by = "USUBJID")
colspan_trt_map <- create_colspan_map(adexsum,
non_active_grp = ctrl_grp,
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = trtvar
)
ref_path <- c("colspan_trt", " ", trtvar, ctrl_grp)
################################################################################
# Define layout and build table:
################################################################################
lyt <- basic_table(show_colcounts = TRUE, colcount_format = "N=xx", top_level_section_div = " ") |>
split_cols_by("colspan_trt", split_fun = trim_levels_to_map(map = colspan_trt_map)) |>
split_cols_by(trtvar) |>
split_cols_by("rrisk_header", nested = FALSE) |>
split_cols_by(trtvar, labels_var = "rrisk_label", split_fun = remove_split_levels(ctrl_grp)) |>
analyze("TRTDURY",
nested = FALSE,
show_labels = "hidden",
afun = a_patyrs_j
)
result <- build_table(lyt, aefup, alt_counts_df = adexsum)
result
Formatted Analysis Function For Proportion Confidence Interval for Factor
Description
Formatted Analysis Function For Proportion Confidence Interval for Factor.
Usage
a_proportion_ci_factor(df, .var, ...)
Arguments
df |
( |
.var |
( |
... |
see |
Value
The rtables::rcell() result.
Examples
a_proportion_ci_factor(
df = DM,
.var = "SEX",
.alt_df = DM,
conf_level = 0.95,
formats = list(prop_ci = jjcsformat_xx("xx.x%, xx.x%")),
method = "clopper-pearson"
)
Formatted Analysis Function For Proportion Confidence Interval for Logical
Description
Formatted Analysis Function For Proportion Confidence Interval for Logical.
Usage
a_proportion_ci_logical(x, .alt_df, conf_level, method, formats)
Arguments
x |
( |
.alt_df |
( |
conf_level |
( |
method |
( |
formats |
( |
Value
The rtables::rcell() result.
Examples
a_proportion_ci_logical(
x = DM$SEX == "F",
.alt_df = DM,
conf_level = 0.95,
formats = list(prop_ci = jjcsformat_xx("xx.xx% - xx.xx%")),
method = "wald"
)
Relative risk estimation
Description
The analysis function a_relative_risk() is used to create a layout element
to estimate the relative risk for response within a studied population. Only
the CMH method is available currently.
The primary analysis variable, vars, is a logical variable indicating
whether a response has occurred for each record.
A stratification variable must be supplied via the
strata element of the variables argument.
Usage
a_relative_risk(
df,
.var,
ref_path,
.spl_context,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
s_relative_risk(
df,
.var,
.ref_group,
.in_ref_col,
variables = list(strata = NULL),
conf_level = 0.95,
method = "cmh",
weights_method = "cmh"
)
Arguments
df |
( |
.var |
( |
ref_path |
( |
.spl_context |
( |
... |
Additional arguments passed to the statistics function. |
.stats |
( |
.formats |
( |
.labels |
( |
.indent_mods |
( |
.ref_group |
( |
.in_ref_col |
( |
variables |
( |
conf_level |
( |
method |
( |
weights_method |
( |
Details
The variance of the CMH relative risk estimate is calculated using the Greenland and Robins (1985) variance estimation.
Value
-
a_relative_risk()returns the corresponding list with formattedrtables::CellValue().
-
s_relative_risk()returns a named list of elementsrel_risk_ciandpval.
Functions
-
a_relative_risk(): Formatted analysis function which is used asafun. Note that the junco specificref_pathand.spl_contextarguments are used for reference column information. -
s_relative_risk(): Statistics function estimating the relative risk for response.
Note
This has been adapted from the odds_ratio functions in the tern package.
Examples
nex <- 100
dta <- data.frame(
"rsp" = sample(c(TRUE, FALSE), nex, TRUE),
"grp" = sample(c("A", "B"), nex, TRUE),
"f1" = sample(c("a1", "a2"), nex, TRUE),
"f2" = sample(c("x", "y", "z"), nex, TRUE),
stringsAsFactors = TRUE
)
l <- basic_table() |>
split_cols_by(var = "grp") |>
analyze(
vars = "rsp",
afun = a_relative_risk,
extra_args = list(
conf_level = 0.90,
variables = list(strata = "f1"),
ref_path = c("grp", "B")
)
)
build_table(l, df = dta)
nex <- 100
dta <- data.frame(
"rsp" = sample(c(TRUE, FALSE), nex, TRUE),
"grp" = sample(c("A", "B"), nex, TRUE),
"f1" = sample(c("a1", "a2"), nex, TRUE),
"f2" = sample(c("x", "y", "z"), nex, TRUE),
stringsAsFactors = TRUE
)
s_relative_risk(
df = subset(dta, grp == "A"),
.var = "rsp",
.ref_group = subset(dta, grp == "B"),
.in_ref_col = FALSE,
variables = list(strata = c("f1", "f2")),
conf_level = 0.90
)
Analysis Function: Sum and Ratio of Sums
Description
Computes one or more of the following statistics for use with
rtables::analyze():
-
"sum":sum(.var) -
"sum_unique":sum(.var)after keeping unique rows byid_var -
"ratio":sum(.var) / sum(denom_by) -
"ratio_unique": same ratio after keeping unique rows byid_var
Both .var and denom_by columns must be numeric (integer, double, or
logical coerced to numeric).
Usage
a_sum_ratio_j(
df,
.var,
.stats = "sum",
denom_by = NULL,
id_var = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL,
na_str = NULL,
...
)
Arguments
df |
( |
.var |
( |
.stats |
( |
denom_by |
( |
id_var |
( |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
na_str |
( |
... |
additional arguments for the lower level functions. |
Value
A RowsVerticalSection for use by rtables.
Author(s)
VR
Examples
df <- data.frame(
USUBJID = c("S01", "S01", "S02", "S03"),
ARM = factor(c("A", "A", "A", "B")),
EVENTS = c(1, 1, 0, 1),
DAYS = c(10, 10, 20, 15)
)
# All 4 stats in a layout (S01 duplicate tests unique logic)
lyt <- basic_table() |>
split_cols_by("ARM") |>
analyze(
"EVENTS",
afun = a_sum_ratio_j,
extra_args = list(
.stats = c("sum", "sum_unique", "ratio", "ratio_unique"),
denom_by = "DAYS",
id_var = "USUBJID"
)
)
build_table(lyt, df)
ANCOVA Summary Function
Description
Combination of tern::s_summary, and ANCOVA based estimates for mean and diff between columns,
based on ANCOVA function s_ancova_j.
Usage
a_summarize_ancova_j(
df,
.var,
.df_row,
ref_path,
.spl_context,
...,
.stats = c("n", "mean_sd", "median", "range", "quantiles", "lsmean_se", "lsmean_ci",
"lsmean_diff_with_ci", "pval"),
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
s_summarize_ancova_j(df, .var, .df_row, .ref_group, .in_ref_col, ...)
Arguments
df |
( |
.var |
( |
.df_row |
( |
ref_path |
( |
.spl_context |
( |
... |
Additional arguments passed to |
.stats |
( |
.formats |
( |
.labels |
( |
.indent_mods |
( |
.ref_group |
( |
.in_ref_col |
( |
Details
Combination of tern::s_summary, and ANCOVA based estimates for mean and diff between columns,
based on ANCOVA function s_ancova_j
Value
-
a_summarize_ancova_j()returns the corresponding list with formattedrtables::CellValue().
returns the statistics from tern::s_summary(x), appended with a new statistics based upon ANCOVA
Functions
-
a_summarize_ancova_j(): Formatted analysis function which is used asafun. Note that the junco specificref_pathand.spl_contextarguments are used for reference column information.
See Also
Other Inclusion of ANCOVA Functions:
a_summarize_aval_chg_diff_j(),
s_ancova_j()
Examples
basic_table() |>
split_cols_by("Species") |>
add_colcounts() |>
analyze(
vars = "Petal.Length",
afun = a_summarize_ancova_j,
show_labels = "hidden",
na_str = tern::default_na_str(),
table_names = "unadj",
var_labels = "Unadjusted comparison",
extra_args = list(
variables = list(arm = "Species", covariates = NULL),
conf_level = 0.95,
.labels = c(lsmean = "Mean", lsmean_diff = "Difference in Means"),
ref_path = c("Species", "setosa")
)
) |>
analyze(
vars = "Petal.Length",
afun = a_summarize_ancova_j,
show_labels = "hidden",
na_str = tern::default_na_str(),
table_names = "adj",
var_labels = "Adjusted comparison (covariates: Sepal.Length and Sepal.Width)",
extra_args = list(
variables = list(
arm = "Species",
covariates = c("Sepal.Length", "Sepal.Width")
),
conf_level = 0.95,
ref_path = c("Species", "setosa")
)
) |>
build_table(iris)
library(dplyr)
library(tern)
df <- iris |> filter(Species == "virginica")
.df_row <- iris
.var <- "Petal.Length"
variables <- list(arm = "Species", covariates = "Sepal.Length * Sepal.Width")
.ref_group <- iris |> filter(Species == "setosa")
conf_level <- 0.95
s_summarize_ancova_j(
df,
.var = .var,
.df_row = .df_row,
variables = variables,
.ref_group = .ref_group,
.in_ref_col = FALSE,
conf_level = conf_level
)
Analysis function 3-column presentation
Description
Analysis functions to produce a 1-row summary presented in
a 3-column layout in the columns (column 1 = N, column 2 = Value, column 3 = Change).
In the difference columns, only 1 column will be presented : difference + CI
When ancova = TRUE, the presented statistics will be based on ANCOVA method (s_summarize_ancova_j).
mean and ci (both for Value (column 2) and CHG (column 3)) using statistic lsmean_ci
mean and ci for the difference column are based on same ANCOVA model using statistic lsmean_diff_with_ci
When ancova = FALSE, descriptive statistics will be used instead.
In the difference column, the 2-sample t-test will be used.
Usage
a_summarize_aval_chg_diff_j(
df,
.df_row,
.spl_context,
ancova = FALSE,
comp_btw_group = TRUE,
ref_path = NULL,
.N_col,
denom = c("N", ".N_col"),
indatavar = NULL,
d = 0,
id = "USUBJID",
interaction_y = FALSE,
interaction_item = NULL,
conf_level = 0.95,
variables = list(arm = "TRT01A", covariates = NULL),
format_na_str = "",
.stats = list(col1 = "count_denom_frac", col23 = "mean_ci_3d", coldiff =
"mean_diff_with_ci"),
.formats = list(col1 = NULL, col23 = "xx.dx (xx.dx, xx.dx)", coldiff =
"xx.dx (xx.dx, xx.dx)"),
.formats_fun = list(col1 = jjcsformat_count_denom_fraction, col23 = jjcsformat_xx,
coldiff = jjcsformat_xx),
multivars = c("AVAL", "AVAL", "CHG"),
weights_emmeans = NULL,
method_combo = c("contrasts", "collapse"),
weights_combo = NULL
)
Arguments
df |
( |
.df_row |
( |
.spl_context |
( |
ancova |
( |
comp_btw_group |
( |
ref_path |
( |
.N_col |
( |
denom |
(
|
indatavar |
( |
d |
(default = 1)
|
id |
( |
interaction_y |
( |
interaction_item |
( |
conf_level |
( |
variables |
(named list of strings)
|
format_na_str |
( |
.stats |
(named |
.formats |
(named |
.formats_fun |
(named |
multivars |
( |
weights_emmeans |
( |
method_combo |
(
For more information see the vignette |
weights_combo |
(
|
Details
See Description
Value
A function that can be used in an analyze function call
See Also
Other Inclusion of ANCOVA Functions:
a_summarize_ancova_j(),
s_ancova_j()
Examples
library(dplyr)
ADEG <- data.frame(
STUDYID = c(
"DUMMY", "DUMMY", "DUMMY", "DUMMY", "DUMMY",
"DUMMY", "DUMMY", "DUMMY", "DUMMY", "DUMMY"
),
USUBJID = c(
"XXXXX01", "XXXXX02", "XXXXX03", "XXXXX04", "XXXXX05",
"XXXXX06", "XXXXX07", "XXXXX08", "XXXXX09", "XXXXX10"
),
TRT01A = c(
"ARMA", "ARMA", "ARMA", "ARMA", "ARMA", "Placebo",
"Placebo", "Placebo", "ARMA", "ARMA"
),
PARAM = c("BP", "BP", "BP", "BP", "BP", "BP", "BP", "BP", "BP", "BP"),
AVISIT = c(
"Visit 1", "Visit 1", "Visit 1", "Visit 1", "Visit 1",
"Visit 1", "Visit 1", "Visit 1", "Visit 1", "Visit 1"
),
AVAL = c(56, 78, 67, 87, 88, 93, 39, 87, 65, 55),
CHG = c(2, 3, -1, 9, -2, 0, 6, -2, 5, 2)
)
ADEG <- ADEG |>
mutate(
TRT01A = as.factor(TRT01A),
STUDYID = as.factor(STUDYID)
)
ADEG$colspan_trt <- factor(ifelse(ADEG$TRT01A == "Placebo", " ", "Active Study Agent"),
levels = c("Active Study Agent", " ")
)
ADEG$rrisk_header <- "Risk Difference (%) (95% CI)"
ADEG$rrisk_label <- paste(ADEG$TRT01A, paste("vs", "Placebo"))
colspan_trt_map <- create_colspan_map(ADEG,
non_active_grp = "Placebo",
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
ref_path <- c("colspan_trt", " ", "TRT01A", "Placebo")
lyt <- basic_table() |>
split_cols_by(
"colspan_trt",
split_fun = trim_levels_to_map(map = colspan_trt_map)
) |>
split_cols_by("TRT01A") |>
split_rows_by(
"PARAM",
label_pos = "topleft",
split_label = "Blood Pressure",
section_div = " ",
split_fun = drop_split_levels
) |>
split_rows_by(
"AVISIT",
label_pos = "topleft",
split_label = "Study Visit",
split_fun = drop_split_levels,
child_labels = "hidden"
) |>
split_cols_by_multivar(
c("AVAL", "AVAL", "CHG"),
varlabels = c("n/N (%)", "Mean (CI)", "CFB (CI)")
) |>
split_cols_by("rrisk_header", nested = FALSE) |>
split_cols_by(
"TRT01A",
split_fun = remove_split_levels("Placebo"),
labels_var = "rrisk_label"
) |>
split_cols_by_multivar(c("CHG"), varlabels = c(" ")) |>
analyze("STUDYID",
afun = a_summarize_aval_chg_diff_j,
extra_args = list(
format_na_str = "-", d = 0,
ref_path = ref_path, variables = list(arm = "TRT01A", covariates = NULL)
)
)
result <- build_table(lyt, ADEG)
result
Tabulation for Exposure Tables
Description
A function to create the appropriate statistics needed for exposure table
Usage
s_summarize_ex_j(
df,
.var,
.df_row,
.spl_context,
comp_btw_group = TRUE,
ref_path = NULL,
ancova = FALSE,
interaction_y,
interaction_item,
conf_level,
daysconv,
variables
)
a_summarize_ex_j(
df,
.var,
.df_row,
.spl_context,
comp_btw_group = TRUE,
ref_path = NULL,
ancova = FALSE,
interaction_y = FALSE,
interaction_item = NULL,
conf_level = 0.95,
variables,
.stats = c("mean_sd", "median", "range", "quantiles", "total_subject_years"),
.formats = c(diff_mean_est_ci = jjcsformat_xx("xx.xx (xx.xx, xx.xx)")),
.labels = c(quantiles = "Interquartile range"),
.indent_mods = NULL,
na_str = rep("NA", 3),
daysconv = 1
)
Arguments
df |
( |
.var |
( |
.df_row |
( |
.spl_context |
( |
comp_btw_group |
( |
ref_path |
( |
ancova |
( |
interaction_y |
( |
interaction_item |
( |
conf_level |
( |
daysconv |
( |
variables |
(named list of strings)
|
.stats |
( |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
na_str |
( |
Details
Creates statistics needed for standard exposure table.
This includes differences and 95% CI and total treatment years.
This is designed to be used as an analysis (afun in analyze) function.
Value
-
a_summarize_ex_j()returns the corresponding list with formattedrtables::CellValue().
Functions
-
s_summarize_ex_j(): Statistics function needed for the exposure tables. -
a_summarize_ex_j(): Formatted analysis function which is used asafun.
Examples
library(dplyr)
ADEX <- ex_adsl |> select(USUBJID, ARM, TRTSDTM, EOSSTT, EOSDY)
trtvar <- "ARM"
ctrl_grp <- "B: Placebo"
cutoffd <- as.Date("2023-09-24")
ADEX <- ADEX |>
create_colspan_var(
non_active_grp = ctrl_grp,
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = trtvar
) |>
mutate(
diff_header = "Difference in Means (95% CI)",
diff_label = paste(!!rlang::sym(trtvar), "vs", ctrl_grp),
TRTDURY = case_when(
!is.na(EOSDY) ~ EOSDY,
TRUE ~ as.integer(cutoffd - as.Date(TRTSDTM) + 1)
)
)
colspan_trt_map <- create_colspan_map(ADEX,
non_active_grp = ctrl_grp,
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = trtvar
)
ref_path <- c("colspan_trt", "", trtvar, ctrl_grp)
lyt <- basic_table() |>
split_cols_by(
"colspan_trt",
split_fun = trim_levels_to_map(map = colspan_trt_map)
) |>
split_cols_by(trtvar) |>
split_cols_by("diff_header", nested = FALSE) |>
split_cols_by(
trtvar,
split_fun = remove_split_levels(ctrl_grp),
labels_var = "diff_label"
) |>
analyze("EOSDY",
afun = a_summarize_ex_j, var_labels = "Duration of treatment (Days)",
show_labels = "visible",
indent_mod = 0L,
extra_args = list(
daysconv = 1,
ref_path = ref_path,
variables = list(arm = trtvar, covariates = NULL),
ancova = TRUE,
comp_btw_group = TRUE
)
)
result <- build_table(lyt, ADEX, alt_counts_df = ADEX)
result
Wrappers Around tern::a_summary() with Row Split Exclusion
Description
These wrappers around tern::a_summary() allow selected row split levels to
be excluded from producing the analysis.
Usage
a_summary_j_with_exclude(df, .var, exclude_levels, .spl_context, ...)
Arguments
df |
( |
.var |
( |
exclude_levels |
( |
.spl_context |
( |
... |
Additional arguments passed to |
Details
tern::a_summary() is a formatted analysis function that computes summary
statistics for a single variable. In typical use within the rtables
framework, the analysis variable is first extracted from a data frame and
then passed to tern::a_summary() as a standalone vector.
a_summary_j_with_exclude() extends this behavior by:
accepting a data frame (
df) as input,checking whether the current row split path should be excluded,
returning
NULLfor excluded row split levels,extracting the analysis variable
.varfor all other row split levels,and passing the resulting vector to
tern::a_summary().
Value
Returns the same type of object as tern::a_summary(), or NULL when the
current row split path is excluded by exclude_levels.
Functions
-
a_summary_j_with_exclude(): Analysis function which can exclude row split levels from producing the analysis. These have to be specified in theexclude_levelsargument, see?do_exclude_splitfor details.
See Also
tern::a_summary(), do_exclude_split()
Examples
df <- data.frame(
USUBJID = 1:8,
AVISIT = factor(rep(c("Baseline", "Week 1"), 4)),
ARM = factor(rep(c("A", "B"), each = 4)),
AVAL = c(1.2, 3, -1.5, 0.8, 3.5, 2, -1.1, 0.3)
)
lyt <- basic_table() |>
split_cols_by("ARM") |>
split_rows_by("AVISIT") |>
analyze(
"AVAL",
afun = a_summary_j_with_exclude,
extra_args = list(exclude_levels = list(AVISIT = "Baseline"))
)
build_table(lyt, df)
Two Tier Analysis Function
Description
a_two_tier(): The analysis function used as an afun in analyze.
This function simulates a final additional level of nesting with a
traditional analyze call inside it.
This makes it possible to create what appear to be group summary or content rows and to optionally or conditionally generate one or more "detail" rows underneath it.
For example, in a disposition table, one might want counts for completed and ongoing patients with no further detail underneath, but a breakdown of specific reasons beneath the count of patients who discontinued treatment.
a_three_tier(): Extends a_two_tier() by adding a third level
of nesting: a group summary outer row, mid-level detail rows (one per level
of inner_var1), and innermost detail rows (one per level of inner_var2)
nested beneath each mid-level row.
Usage
a_two_tier(
df,
labelstr = NULL,
.var,
.N_col,
.df_row,
inner_var,
drill_down_levs,
.spl_context,
use_all_levels = FALSE,
grp_fun,
detail_fun,
.alt_df_full = NULL,
...
)
a_three_tier(
df,
labelstr = NULL,
.var,
.N_col,
.df_row,
inner_var1,
inner_var2,
drill_down_levs,
.spl_context,
use_all_levels = FALSE,
grp_fun,
detail_fun,
.alt_df_full = NULL,
...
)
Arguments
df |
( |
labelstr |
( |
.var |
( |
.N_col |
( |
.df_row |
( |
inner_var |
( |
drill_down_levs |
( |
.spl_context |
( |
use_all_levels |
( |
grp_fun |
( |
detail_fun |
( |
.alt_df_full |
( |
... |
additional arguments passed directly to |
inner_var1 |
( |
inner_var2 |
( |
Details
a_two_tier(): Both the analysis variable and inner_var must be factors.
Detail rows are differentiated by having an indent mod of one, causing them
to hang indented under their corresponding group row.
a_three_tier(): The analysis variable, inner_var1, and inner_var2 must all be
factors. Mid-level rows are indented by one and innermost rows by two,
relative to the group summary row.
Value
a_two_tier(): A RowsVerticalSection object including both the group row and all
detail rows, if applicable, for the facet.
a_three_tier(): A RowsVerticalSection object including the group row, mid-level
detail rows, and innermost detail rows, if applicable, for the facet.
Note
In its current form, this function may not retain any formatting or
labeling instructions added by grp_fun or detail_fun, and it will
override any .indent_mods values specified by them. This behavior may
change in future versions.
Author(s)
GB, WW.
Examples
# Example 1
lyt_obs_levels <- basic_table() |>
split_cols_by("ARM") |>
split_rows_by("EOSSTT", child_labels = "hidden") |>
analyze("EOSSTT",
afun = a_two_tier,
extra_args = list(
grp_fun = simple_analysis,
detail_fun = simple_analysis,
inner_var = "DCSREAS",
drill_down_levs = "DISCONTINUED"
)
)
tbl <- build_table(lyt_obs_levels, ex_adsl)
tbl
lyt_all_levels <- basic_table() |>
split_cols_by("ARM") |>
split_rows_by("EOSSTT", child_labels = "hidden") |>
analyze("EOSSTT",
afun = a_two_tier,
extra_args = list(
grp_fun = simple_analysis,
detail_fun = simple_analysis,
inner_var = "DCSREAS",
drill_down_levs = "DISCONTINUED",
use_all_levels = TRUE
)
)
adsl_subset <- subset(ex_adsl, DCSREAS != "ADVERSE EVENT")
levels(adsl_subset$DCSREAS)
tbl_all_levels <- build_table(lyt_all_levels, adsl_subset)
tbl_all_levels
tbl_obs_levels <- build_table(lyt_obs_levels, adsl_subset)
tbl_obs_levels
# Example 2
library(dplyr)
trtvar <- "ARM"
ctrl_grp <- "B: Placebo"
adsl <- ex_adsl |> select(c("USUBJID", "STRATA1", "EOSSTT", "DCSREAS", all_of(trtvar)))
adsl$colspan_trt <- factor(
ifelse(adsl[[trtvar]] == ctrl_grp, " ", "Active Study Agent"),
levels = c("Active Study Agent", " ")
)
adsl$rrisk_header <- "Risk Difference (%) (95% CI)"
adsl$rrisk_label <- paste(adsl[[trtvar]], paste("vs", ctrl_grp))
colspan_trt_map <- create_colspan_map(
df = adsl,
non_active_grp = ctrl_grp,
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = trtvar
)
a_freq_j_args <- list(
.stats = "count_unique_fraction",
denom = "n_altdf",
ref_path = c("colspan_trt", " ", trtvar, ctrl_grp)
)
two_tier_args <- list(
grp_fun = a_freq_j,
detail_fun = a_freq_j,
inner_var = "DCSREAS",
drill_down_levs = "DISCONTINUED"
)
lyt_rrisk <- basic_table() |>
split_cols_by("colspan_trt", split_fun = trim_levels_to_map(map = colspan_trt_map)) |>
split_cols_by(trtvar) |>
split_cols_by("rrisk_header", nested = FALSE) |>
split_cols_by(trtvar, labels_var = "rrisk_label", split_fun = remove_split_levels(ctrl_grp)) |>
split_rows_by("STRATA1") |>
split_rows_by("EOSSTT", child_labels = "hidden") |>
analyze("EOSSTT", afun = a_two_tier, extra_args = c(two_tier_args, a_freq_j_args))
adsl_subset <- subset(
adsl,
EOSSTT != "COMPLETED" & (is.na(DCSREAS) | DCSREAS != "PROTOCOL VIOLATION")
)
tbl_rrisk <- build_table(lyt_rrisk, adsl_subset, alt_counts_df = adsl_subset)
tbl_rrisk
Analysis and Content Summary Function Producing Blank Line
Description
Analysis and Content Summary Function Producing Blank Line
Usage
ac_blank_line(df, labelstr = "")
Arguments
df |
( |
labelstr |
( |
Shortcut Layout Function for Standard Continuous Variable Analysis
Description
Shortcut Layout Function for Standard Continuous Variable Analysis
Usage
analyze_values(lyt, vars, ..., formats)
Arguments
lyt |
( |
vars |
( |
... |
additional arguments for the lower level functions. |
formats |
( |
Value
Modified layout.
Pruning Function for pruning based on a fraction and/or a difference from the control arm
Description
This is a pruning constructor function which identifies records to be pruned based on the the fraction from the percentages. In addition to just looking at a fraction within an arm, this function also allows further flexibility to also prune based on a comparison versus the control arm.
Usage
bspt_pruner(
fraction = 0.05,
keeprowtext = "Analysis set: Safety",
reg_expr = FALSE,
control = NULL,
diff_from_control = NULL,
only_more_often = TRUE,
cols = c("TRT01A")
)
Arguments
fraction |
( |
keeprowtext |
( |
reg_expr |
( |
control |
( |
diff_from_control |
( |
only_more_often |
( |
cols |
( |
Value
Function that can be utilized as pruning function in prune_table.
Examples
ADSL <- data.frame(
USUBJID = c(
"XXXXX01", "XXXXX02", "XXXXX03", "XXXXX04", "XXXXX05",
"XXXXX06", "XXXXX07", "XXXXX08", "XXXXX09", "XXXXX10"
),
TRT01P = c(
"ARMA", "ARMB", "ARMA", "ARMB", "ARMB",
"Placebo", "Placebo", "Placebo", "ARMA", "ARMB"
),
FASFL = c("Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y"),
SAFFL = c("N", "N", "N", "N", "N", "N", "N", "N", "N", "N"),
PKFL = c("N", "N", "N", "N", "N", "N", "N", "N", "N", "N")
)
ADSL <- ADSL |>
dplyr::mutate(TRT01P = as.factor(TRT01P)) |>
dplyr::mutate(SAFFL = factor(SAFFL, c("Y", "N"))) |>
dplyr::mutate(PKFL = factor(PKFL, c("Y", "N")))
lyt <- basic_table() |>
split_cols_by("TRT01P") |>
add_overall_col("Total") |>
split_rows_by(
"FASFL",
split_fun = drop_and_remove_levels("N"),
child_labels = "hidden"
) |>
analyze("FASFL",
var_labels = "Analysis set:",
afun = a_freq_j,
show_labels = "visible",
extra_args = list(label = "Full", .stats = "count_unique_fraction")
) |>
split_rows_by(
"SAFFL",
split_fun = remove_split_levels("N"),
child_labels = "hidden"
) |>
analyze("SAFFL",
var_labels = "Analysis set:",
afun = a_freq_j,
show_labels = "visible",
extra_args = list(label = "Safety", .stats = "count_unique_fraction")
) |>
split_rows_by(
"PKFL",
split_fun = remove_split_levels("N"),
child_labels = "hidden"
) |>
analyze("PKFL",
var_labels = "Analysis set:",
afun = a_freq_j,
show_labels = "visible",
extra_args = list(label = "PK", .stats = "count_unique_fraction")
)
result <- build_table(lyt, ADSL)
result
result <- prune_table(
result,
prune_func = bspt_pruner(
fraction = 0.05,
keeprowtext = "Safety",
cols = c("Total")
)
)
result
Building Model Formula
Description
This builds the model formula which is used inside fit_mmrm_j() and provided
to mmrm::mmrm() internally. It can be instructive to look at the resulting
formula directly sometimes. In particular, if a subgroup variable is included
in vars, then the formula will include the interaction of subgroup with
arm and visit.
Usage
build_formula(
vars,
cor_struct = c("unstructured", "toeplitz", "heterogeneous toeplitz", "ante-dependence",
"heterogeneous ante-dependence", "auto-regressive", "heterogeneous auto-regressive",
"compound symmetry", "heterogeneous compound symmetry")
)
Arguments
vars |
( |
cor_struct |
( |
Value
Formula to use in mmrm::mmrm().
Examples
vars <- list(
response = "AVAL",
covariates = c("RACE", "SEX"),
id = "USUBJID",
arm = "ARMCD",
visit = "AVISIT",
subgroup = "REGION"
)
build_formula(vars, "auto-regressive")
build_formula(vars)
c_function for proportion of TRUE in logical vector
Description
A simple statistics function which prepares the numbers with percentages in the required format, for use in a split content row. The denominator here is from the column N. Note that we don't use here .alt_df because that might not have required row split variables available.
Usage
c_proportion_logical(x, labelstr, label_fstr, format, .N_col)
Arguments
x |
( |
labelstr |
( |
label_fstr |
( |
format |
( |
.N_col |
( |
Value
The rtables::in_rows() result with the proportion statistics.
See Also
s_proportion_logical() for the related statistics function.
Simple Content Row Function to Count Rows
Description
Simple Content Row Function to Count Rows
Usage
c_row_counts(df, labelstr, label_fstr)
Value
a VertalRowsSection object (as returned by rtables::in_rows()
containing counts from the data.
Simple Content Row Function to Count Rows from Alternative Data
Description
Simple Content Row Function to Count Rows from Alternative Data
Usage
c_row_counts_alt(df, labelstr, label_fstr, .alt_df)
Value
a VertalRowsSection object (as returned by rtables::in_rows()
containing counts from the alt data.
Categorize p-values
Description
Assigns each p-value to a category defined by a named list of lower and upper bounds.
Usage
categorize_pval(p, pvalcat)
Arguments
p |
( |
pvalcat |
( |
Details
Categories are evaluated in the order supplied by pvalcat. Bounds
are lower-inclusive and upper-exclusive, except that the upper bound of
the final category is inclusive. P-values that do not fall in a category,
including missing values, are returned as NA_character_.
Value
A character vector of category labels, with one element per value in
p.
Examples
pvalcat <- list(
"<0.001" = c(0, 0.001),
"0.001 to <0.05" = c(0.001, 0.05),
">=0.05" = c(0.05, 1)
)
categorize_pval(c(0, 0.001, 0.049, 0.05, 1, NA), pvalcat)
Check Word Wrapping
Description
Check a set of column widths for word-breaking wrap behavior.
Usage
check_wrap_nobreak(tt, colwidths, fontspec)
Arguments
tt |
( |
colwidths |
( |
fontspec |
( |
Value
TRUE if the wrap is able to be done without breaking words,
FALSE if wordbreaking is required to apply colwidths.
Cochran-Mantel-Haenszel Row Mean Scores test
Description
See https://psiaims.github.io/CAMIS/Comp/r-sas_cmh.html for a general comparison overview between R and SAS.
Usage
a_cmhrms_j(
df,
.var,
ref_path,
.spl_context,
.ref_group,
.in_ref_col,
.df_row,
...,
variables,
collapse_combo = TRUE,
.stats = NULL,
.formats = NULL,
.indent_mods = NULL,
.labels = NULL
)
s_cmhrms_j(
df,
.var,
.ref_group,
.in_ref_col,
...,
.df_row,
variables,
collapse_combo = FALSE
)
a_cmhrms_j_with_exclude(
df,
exclude_levels,
.var,
.spl_context,
.ref_group,
.in_ref_col,
.df_row,
...,
.stats = NULL,
.formats = NULL,
.indent_mods = NULL,
.labels = NULL
)
Arguments
df |
( |
.var |
( |
ref_path |
( |
.spl_context |
( |
.ref_group |
( |
.in_ref_col |
( |
.df_row |
( |
... |
additional arguments for the lower level functions. |
variables |
( |
collapse_combo |
( |
.stats |
( |
.formats |
(named |
.indent_mods |
(named |
.labels |
(named |
exclude_levels |
( |
Value
-
s_cmhrms_ja single element list containing the p-value from row mean score test. -
a_cmhrms_jaVerticalRowsSectionobject (single row).
Functions
-
a_cmhrms_j(): Formatted analysis function which is used asafun. -
s_cmhrms_j(): Statistics function for the calculation of the p-value based upon the row mean scores test. -
a_cmhrms_j_with_exclude(): Wrapper for theafunwhich can exclude row split levels from producing the analysis. These have to be specified in theexclude_levelsargument, see?do_exclude_splitfor details.
Summary Analysis Function for Compliance Columns
Description
A simple statistics function which prepares the numbers with percentages in the required format, for use in a split content row. The denominator here is from the expected visits column.
Usage
cmp_cfun(df, labelstr, .spl_context, variables, formats)
Arguments
df |
( |
labelstr |
( |
.spl_context |
( |
variables |
( |
formats |
( |
Value
The rtables::in_rows() result with the counts and proportion statistics.
See Also
cmp_post_fun() for the corresponding split function.
Split Function for Compliance Columns
Description
Here we just split into 3 columns for expected, received and missing visits.
Usage
cmp_post_fun(ret, spl, fulldf, .spl_context)
cmp_split_fun(df, spl, vals = NULL, labels = NULL, trim = FALSE, .spl_context)
Arguments
ret |
( |
spl |
( |
fulldf |
( |
.spl_context |
( |
df |
( |
vals |
( |
labels |
(named |
trim |
( |
Value
a split function for use with rtables::split_rows_by when creating proportion-based tables with compliance columns.
See Also
rtables::make_split_fun() describing the requirements for this kind of
post-processing function.
Statistics within the column space
Description
A function used for obtaining statistics within the columns of your table. Used in change from baseline tables. This takes the visit names as its row labels.
Usage
column_stats(
df,
.var,
.spl_context,
.formats = NULL,
formats_var = NULL,
exclude_visits = c("Baseline (DB)"),
var_names = c("AVAL", "CHG", "BASE")
)
Arguments
df |
( |
.var |
( |
.spl_context |
( |
.formats |
(named |
formats_var |
( |
exclude_visits |
Visits to exclude for the second/third part of the columns ("BASE", "CHG"). |
var_names |
( |
Value
An analysis function (for use with rtables::analyze) implementing
the specified statistics.
Typically used in a layout that has been setup by stats_in_cols_setup()
Examples
# example code
library(dplyr)
advs <- ex_advs |>
filter(AVISIT %in% toupper(c("Screening", "Baseline", "Week 1 Day 8", "Week 2 Day 15"))) |>
mutate(AVISIT = droplevels(AVISIT)) |>
filter(PARAMCD %in% c("DIABP", "SYSBP"))
advs_fmt <- tribble(
~PARAMCD, ~fmt_d,
"DIABP", list(
mean = "xx.xx", sd = "xx.xxx", se = "xx.xxx", median = "xx.xx",
min = "xx.x", max = "xx.x", mean_sd = "xx.xx (xx.xxx)"
),
"SYSBP", list(
mean = "xx.x", sd = "xx.xx", se = "xx.xx", median = "xx.x",
min = "xx.", max = "xx.", mean_sd = "xx.x (xx.xx)"
)
)
advs <- left_join(advs, advs_fmt)
mysplitfun <- make_split_fun(
post = list(stats_in_cols_setup())
)
lyt <- basic_table() |>
split_cols_by_multivar(
c("AVAL", "BASE", "CHG"),
varlabels = c("Visit Values", " ", "Change from Baseline")
) |>
split_cols_by("STUDYID", split_fun = mysplitfun) |>
split_rows_by("PARAM", split_fun = drop_split_levels) |>
split_rows_by("ARMCD", labels_var = "ARM") |>
analyze("AVISIT", afun = column_stats, extra_args = list(
exclude_visits = toupper(c("Baseline", "Screening")),
.formats = "default",
formats_var = "fmt_d"
))
result <- build_table(lyt, advs, round_type = "sas")
head(result, 20)
Conditional Removal of Facets
Description
Conditional Removal of Facets
Usage
cond_rm_facets(
facets = NULL,
facets_regex = NULL,
ancestor_pos = 1,
split = NULL,
split_regex = NULL,
value = NULL,
value_regex = NULL,
keep_matches = FALSE
)
Arguments
facets |
( |
facets_regex |
( |
ancestor_pos |
( |
split |
( |
split_regex |
( |
value |
( |
value_regex |
( |
keep_matches |
( |
Details
Facet removal occurs when the specified condition(s)
on the split(s) and or value(s) are met within at least one
of the split_context rows indicated by ancestor_pos; otherwise
the set of facets is returned unchanged.
If facet removal is performed, either all facets which match facets (or
facets_regex will be removed ( the default keep_matches == FALSE
case), or all non-matching facets will be removed (when
keep_matches_only == TRUE).
Value
A function suitable for use in make_split_fun's
post argument which encodes the specified condition.
Note
A degenerate table is likely to be returned if all facets are removed.
Examples
rm_a_from_placebo <- cond_rm_facets(
facets = "A",
ancestor_pos = NA,
value_regex = "Placeb",
split = "ARM"
)
mysplit <- make_split_fun(post = list(rm_a_from_placebo))
lyt <- basic_table() |>
split_cols_by("ARM") |>
split_cols_by("STRATA1", split_fun = mysplit) |>
analyze("AGE", mean, format = "xx.x")
build_table(lyt, ex_adsl)
rm_bc_from_combo <- cond_rm_facets(
facets = c("B", "C"),
ancestor_pos = -1,
value_regex = "Combi"
)
mysplit2 <- make_split_fun(post = list(rm_bc_from_combo))
lyt2 <- basic_table() |>
split_cols_by("ARM") |>
split_cols_by("STRATA1", split_fun = mysplit2) |>
analyze("AGE", mean, format = "xx.x")
tbl2 <- build_table(lyt2, ex_adsl)
tbl2
rm_bc_from_combo2 <- cond_rm_facets(
facets_regex = "^A$",
ancestor_pos = -1,
value_regex = "Combi",
keep_matches = TRUE
)
mysplit3 <- make_split_fun(post = list(rm_bc_from_combo2))
lyt3 <- basic_table() |>
split_cols_by("ARM") |>
split_cols_by("STRATA1", split_fun = mysplit3) |>
analyze("AGE", mean, format = "xx.x")
tbl3 <- build_table(lyt3, ex_adsl)
stopifnot(identical(cell_values(tbl2), cell_values(tbl3)))
Formatting functions for count and fraction, and for count denominator and fraction values
Description
Formats a count together with fraction (and/or denominator) with special
consideration when count is 0, or fraction is 1.
See also: tern::format_count_fraction_fixed_dp()
Usage
jjcsformat_cnt_den_fract_fct(
d = 1,
type = c("count_fraction", "count_denom_fraction", "fraction_count_denom"),
verbose = FALSE,
legacy = FALSE
)
jjcsformat_count_fraction(x, round_type = valid_round_type, output, ...)
jjcsformat_count_denom_fraction(x, round_type = valid_round_type, output, ...)
jjcsformat_count_denom_fraction_legacy(
x,
round_type = valid_round_type,
output,
...
)
jjcsformat_fraction_count_denom(x, round_type = valid_round_type, output, ...)
jjcsformat_fraction_count_denom_legacy(
x,
round_type = valid_round_type,
output,
...
)
Arguments
d |
( |
type |
( |
verbose |
( |
legacy |
( |
x |
( |
round_type |
( |
output |
( |
... |
Additional arguments passed to other methods. |
Value
A formatting function to format input into string in the format count / denom (ratio percent). If count
is 0, the format is 0. If fraction is >0.99, the format is
count / denom (>99.9 percent)
See Also
Other JJCS formatting functions:
jjcsformat_fraction(),
jjcsformat_xx()
Examples
jjcsformat_count_fraction(c(7, 0.7))
jjcsformat_count_fraction(c(70000, 70000 / 70001))
jjcsformat_count_fraction(c(235, 235 / 235))
fmt <- jjcsformat_cnt_den_fract_fct(type = "count_fraction", d = 2)
fmt(c(23, 23 / 235))
jjcsformat_count_denom_fraction(c(7, 10, 0.7))
jjcsformat_count_denom_fraction(c(70000, 70001, 70000 / 70001))
jjcsformat_count_denom_fraction(c(235, 235, 235 / 235))
fmt <- jjcsformat_cnt_den_fract_fct(type = "count_denom_fraction", d = 2)
fmt(c(23, 235, 23 / 235))
jjcsformat_count_denom_fraction_legacy(c(0, 235, 0 / 235))
jjcsformat_fraction_count_denom(c(7, 10, 0.7))
jjcsformat_fraction_count_denom(c(70000, 70001, 70000 / 70001))
jjcsformat_fraction_count_denom(c(235, 235, 235 / 235))
fmt <- jjcsformat_cnt_den_fract_fct(type = "fraction_count_denom", d = 2)
fmt(c(23, 235, 23 / 235))
jjcsformat_fraction_count_denom_legacy(c(0, 235, 0 / 235))
Count Pruner
Description
This is a pruning constructor function which identifies records to be pruned based on the count (assumed to be the first statistic displayed when a compound statistic (e.g., ## / ## (XX.X percent) is presented).
Usage
count_pruner(
count = 0,
cat_include = NULL,
cat_exclude = NULL,
cols = c("TRT01A")
)
Arguments
count |
( |
cat_include |
( |
cat_exclude |
( |
cols |
( |
Value
Function that can be utilized as pruning function in prune_table.
Examples
ADSL <- data.frame(
USUBJID = c(
"XXXXX01", "XXXXX02", "XXXXX03", "XXXXX04", "XXXXX05",
"XXXXX06", "XXXXX07", "XXXXX08", "XXXXX09", "XXXXX10"
),
TRT01P = factor(
c(
"ARMA", "ARMB", "ARMA", "ARMB", "ARMB",
"Placebo", "Placebo", "Placebo", "ARMA", "ARMB"
)
),
FASFL = c("Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y"),
SAFFL = c("N", "N", "N", "N", "N", "N", "N", "N", "N", "N"),
PKFL = c("N", "N", "N", "N", "N", "N", "N", "N", "N", "N")
)
lyt <- basic_table() |>
split_cols_by("TRT01P") |>
add_overall_col("Total") |>
analyze("FASFL",
var_labels = "Analysis set:",
afun = a_freq_j,
extra_args = list(label = "Full", val = "Y"),
show_labels = "visible"
) |>
analyze("SAFFL",
var_labels = "Analysis set:",
afun = a_freq_j,
extra_args = list(label = "Safety", val = "Y"),
show_labels = "visible"
) |>
analyze("PKFL",
var_labels = "Analysis set:",
afun = a_freq_j,
extra_args = list(label = "PK", val = "Y"),
show_labels = "visible"
)
result <- build_table(lyt, ADSL)
result
result <- prune_table(
result,
prune_func = count_pruner(cat_exclude = c("Safety"), cols = "Total")
)
result
Creation of Column Spanning Mapping Dataframe
Description
A function used for creating a data frame containing the map that is compatible with
the rtables split function rtables::trim_levels_to_map().
Usage
create_colspan_map(
df,
non_active_grp = c("Placebo"),
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = "TRT01A",
active_first = TRUE
)
Arguments
df |
( |
non_active_grp |
( |
non_active_grp_span_lbl |
( |
active_grp_span_lbl |
( |
colspan_var |
( |
trt_var |
( |
active_first |
( |
Details
This function creates a data frame containing the map that is compatible with the rtables split function
rtables::trim_levels_to_map().
The levels of the specified trt_var variable will be stored within the trt_var variable
and the colspan_var variable will contain the corresponding spanning header value for each treatment group.
Value
A data frame that contains the map to be used with the rtables split function
rtables::trim_levels_to_map().
See Also
rtables::add_combo_levels() for creating split functions that utilize combination levels.
Examples
library(tibble)
df <- tribble(
~TRT01A,
"Placebo",
"Active 1",
"Active 2"
)
df$TRT01A <- factor(df$TRT01A, levels = c("Placebo", "Active 1", "Active 2"))
colspan_map <- create_colspan_map(
df = df,
non_active_grp = c("Placebo"),
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
colspan_map
Creation of Column Spanning Variables
Description
A function used for creating a spanning variable for treatment groups.
Usage
create_colspan_var(
df,
non_active_grp = c("Placebo"),
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
Arguments
df |
( |
non_active_grp |
( |
non_active_grp_span_lbl |
( |
active_grp_span_lbl |
( |
colspan_var |
( |
trt_var |
( |
Details
This function creates a spanning variable for treatment groups that is intended to be used within the column space.
Value
A data frame that contains the new variable as specified in colspan_var.
Examples
library(tibble)
df <- tribble(
~TRT01A,
"Placebo",
"Active 1",
"Active 2"
)
df$TRT01A <- factor(df$TRT01A, levels = c("Placebo", "Active 1", "Active 2"))
colspan_var <- create_colspan_var(
df = df,
non_active_grp = c("Placebo"),
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Treatment",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
colspan_var
Utilities for the Current Column Split Path
Description
These helper functions are intended for use in rtables custom analysis functions that depend on the current column split context.
Usage
cur_col_split_path(.spl_context)
in_column(col_path, .spl_context)
Arguments
.spl_context |
( |
col_path |
( The special value
|
Value
-
cur_col_split_path()returns a character vector containing the current column split path extracted from.spl_context, interleaved asc(var1, val1, var2, val2, ...).
-
in_column()returns a single logical value indicating whether the current column split matches the specifiedcol_path.
Functions
-
cur_col_split_path(): Get the current column split path. -
in_column(): Determine whether a given column path matches the current column split path.
Author(s)
WW
See Also
-
rtables::col_paths()for obtaining column paths from a built table.
Examples
.spl_context_1 <- data.frame(
cur_col_split = I(list(c("ARM"))),
cur_col_split_val = I(list(c("Placebo")))
)
.spl_context_2 <- data.frame(
cur_col_split = I(list(c("ARM", "desc_stat"))),
cur_col_split_val = I(list(c("Placebo", "N")))
)
cur_col_split_path(.spl_context_1)
cur_col_split_path(.spl_context_2)
in_column(c("ARM", "Placebo"), .spl_context_1)
in_column(c("ARM", "*"), .spl_context_1)
in_column(c("ARM", "X"), .spl_context_1)
in_column(c("ARM", "*", "desc_stat", "N"), .spl_context_2)
in_column(c("ARM", "*", "desc_stat", "Mean"), .spl_context_2)
# Use in an rtables custom analysis function.
data <- formatters::ex_adsl
data$desc_stat <- "phantom"
# analysis function
a_N_mean <- function(x, .spl_context) {
if (in_column(c("ARM", "*", "desc_stat", "N"), .spl_context)) {
rcell(length(x))
} else if (in_column(c("ARM", "*", "desc_stat", "Mean"), .spl_context)) {
rcell(mean(x), format = "xx.x")
} else {
rcell(NULL)
}
}
combodf <- data.frame(
valname = c("N", "Mean"),
label = c("N", "Mean"),
levelcombo = I(list(select_all_levels, select_all_levels)),
exargs = I(list(list(), list()))
)
lyt <- basic_table() |>
split_cols_by("ARM") |>
split_cols_by(
"desc_stat",
split_fun = add_combo_levels(combodf, keep_levels = c("N", "Mean"))
) |>
analyze("AGE", afun = a_N_mean)
tbl <- build_table(lyt, data)
tbl
Get default statistical methods and their associated formats, labels, and indent modifiers
Description
Utility functions to get valid statistic methods for different method groups
(.stats) and their associated formats (.formats), labels (.labels), and indent modifiers
(.indent_mods). This utility is used across junco, but some of its working principles can be
seen in tern::analyze_vars().
Usage
junco_get_stats(
method_groups = "analyze_vars_numeric",
stats_in = NULL,
custom_stats_in = NULL,
add_pval = FALSE
)
junco_get_formats_from_stats(stats, formats_in = NULL, levels_per_stats = NULL)
junco_get_labels_from_stats(
stats,
labels_in = NULL,
levels_per_stats = NULL,
label_attr_from_stats = NULL
)
get_label_attr_from_stats(x_stats)
junco_get_indents_from_stats(stats, indents_in = NULL, levels_per_stats = NULL)
format_stats(
x_stats,
method_groups,
stats_in,
formats_in,
labels_in,
indents_in,
.cell_footnotes = list(NULL),
.row_footnotes = list(NULL)
)
junco_default_stats
junco_default_formats
junco_default_labels
junco_default_indents
Arguments
method_groups |
( |
stats_in |
( |
custom_stats_in |
( |
add_pval |
( |
stats |
( |
formats_in |
(named |
levels_per_stats |
(named |
labels_in |
(named |
label_attr_from_stats |
(named |
x_stats |
( |
indents_in |
(named |
.cell_footnotes |
( |
.row_footnotes |
( |
Format
-
junco_default_statsis a named list of available statistics, with each element named for their corresponding statistical method group.
-
junco_default_formatsis a named vector of available default formats, with each element named for their corresponding statistic.
-
junco_default_labelsis a namedcharactervector of available default labels, with each element named for their corresponding statistic.
-
junco_default_indentsis a namedintegervector of available default indents, with each element named for their corresponding statistic. Only indentations different from zero need to be recorded here.
Details
Current choices for type are counts and numeric for tern::analyze_vars() and affect junco_get_stats().
Value
-
junco_get_stats()returns acharactervector of statistical methods.
-
junco_get_formats_from_stats()returns a named list of formats as strings or functions.
-
junco_get_labels_from_stats()returns a named list of labels as strings.
-
junco_get_indents_from_stats()returns a named list of indentation modifiers as integers. By default all of the indentations will be zero.
-
format_stats()returns the correspondingly formattedrtables::in_rows()result.
Functions
-
junco_get_stats(): Get statistics available for a given method group (analyze function). To check available defaults seejunco_default_statslist. -
junco_get_formats_from_stats(): Get formats corresponding to a list of statistics. To check available defaults see listjunco_default_formats. -
junco_get_labels_from_stats(): Get labels corresponding to a list of statistics. To check for available defaults see listjunco_default_labels. -
get_label_attr_from_stats(): Get label attributes from statistics list. -
junco_get_indents_from_stats(): Get row indent modifiers corresponding to a list of statistics/rows. -
format_stats(): Format statistics results according to format specifications. -
junco_default_stats: Named list of available statistics by method group forjunco. -
junco_default_formats: Named vector of default formats forjunco. -
junco_default_labels: Namedcharactervector of default labels forjunco. -
junco_default_indents: Namedintegervector of default indents forjunco.
Note
These defaults are experimental because we use the names of functions to retrieve the default statistics. This should be generalized in groups of methods according to more reasonable groupings.
These functions have been modified from the tern file utils_default_stats_formats_labels.R.
This file contains junco specific wrappers of functions called within the afun functions,
in order to point to junco specific default statistics, formats and labels.
Formats in tern or junco and rtables can be functions that take in the table cell value and
return a string. This is well documented in vignette('custom_appearance', package = 'rtables').
Default String Mapping for Special Characters
Description
A tibble that maps special characters to their UTF-8 equivalents for use in RTF output. Currently it maps ">=" and "<=" to the Unicode characters.
Usage
default_str_map
Value
A tibble with columns 'pattern' and 'value', where 'pattern' contains the string to be replaced and 'value' contains the replacement.
Difference in Means
Description
Computes estimates and associated inferential statistics for the estimand defined as the difference in population means between two distributions.
The following quantities are available:
- diff_means_n1
Sample size of Group 1.
- diff_means_n2
Sample size of Group 2.
- diff_means_est
Point estimate of the difference in population means.
- diff_means_se
Standard error of the estimator of the difference in population means.
- diff_means_est_se
The point estimate and the standard error.
- diff_means_ci
Confidence interval for the difference in population means.
- diff_means_est_ci
The point estimate and the confidence interval.
Usage
s_diff_means(df1, df2, .var, paired = FALSE, paired_by = NULL, ...)
a_diff_means(
df,
.var,
.spl_context,
ref_path = NULL,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
Arguments
df1 |
( |
df2 |
( |
.var |
( |
paired |
( |
paired_by |
( |
... |
Additional named arguments passed to |
df |
( |
.spl_context |
( |
ref_path |
( This is a workaround for an rtables limitation in supporting
|
.stats |
( Available options are:
If |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
Details
Supports both non-paired and paired samples. For non-paired samples, the estimator is defined as the difference between sample means. For paired samples, the estimator is defined as the mean of within-pair differences.
Inferential statistics, including standard errors and confidence intervals,
are obtained using a t-distribution framework via the internal
safe_t_test() function.
It supports only numeric variables.
Only complete (non-missing) observations are used in statistical computations.
Non-finite values (i.e., Inf, -Inf) are not allowed.
Value
-
s_diff_means()returns a namedlistcontaining the quantities described in the Description section.
-
a_diff_means()returns formattedrtables::in_rows()result with the quantities requested in.stats.
Functions
-
s_diff_means(): Statistical function that computes estimates of the difference in means. The first sample is taken fromdf1[[.var]]and the second fromdf2[[.var]].If
paired = FALSE, missing values are removed separately from each sample prior to statistical computations. Ifpaired = TRUE, observations are matched usingpaired_byprior to statistical analysis, and only complete pairs are used.Data extraction, alignment, and missing-value handling are delegated to the internal
extract_vectors()function, which prepares cleaned numeric vectors for both paired and unpaired settings.Inferential statistics are then computed using
safe_t_test()applied to the processed vectors. -
a_diff_means(): Formatted analysis function which is used asafuninrtables::analyze().The sample from the first distribution is
df[[.var]], and the sample from the second distribution is.ref_group[[.var]], where.ref_groupis computed byget_ref_info()using.spl_contextandref_path.If
ref_path = NULL, thena_diff_means()returns anrtables::in_rows()result with an emptyformatted_cellfor every statistic specified in.stats.
Author(s)
WW
See Also
safe_t_test(), extract_vectors()
Examples
## Statistics function:
df1 <- data.frame(id = c("A", "B", "C", "D"), value = 1:4)
df2 <- data.frame(id = c("A", "C", "D", "E", "F"), value = c(3:1, NA, 16))
# Unpaired samples.
s_diff_means(df1, df2, "value", conf.level = .8)
# Paired samples.
s_diff_means(df1, df2, "value", paired = TRUE, paired_by = "id")
## Analysis function:
lyt <- basic_table() |>
split_cols_by("ARM") |>
split_rows_by(
"PARAMCD",
labels_var = "PARAM",
split_fun = keep_split_levels(c("SYSBP", "DIABP"))
) |>
split_rows_by(
"AVISIT",
split_fun = keep_split_levels(c("BASELINE", "WEEK 1 DAY 8"))
) |>
analyze(
"AVAL",
afun = tern::a_summary,
extra_args = list(.stats = c("n", "mean")),
show_labels = "hidden"
) |>
analyze(
"AVAL",
afun = a_diff_means,
table_names = "aval_diff",
extra_args = list(
.stats = "diff_means_est_ci",
ref_path = c("ARM", "B: Placebo")
),
show_labels = "hidden"
)
tbl <- build_table(lyt, formatters::ex_advs)
tbl
Predicate to Check if Split Should be Excluded
Description
Predicate to Check if Split Should be Excluded
Usage
do_exclude_split(exclude_levels, .spl_context)
Arguments
exclude_levels |
( |
.spl_context |
( |
Value
TRUE if the current split context matches any of the exclude levels,
FALSE otherwise.
Examples
do_exclude_split(
exclude_levels = list(AVISIT = "Baseline"),
.spl_context = data.frame(
split = c("AVISIT", "ARM"),
value = c("Week 4", "Placebo")
)
)
do_exclude_split(
exclude_levels = list(AVISIT = "Baseline"),
.spl_context = data.frame(
split = c("AVISIT", "ARM"),
value = c("Baseline", "Placebo")
)
)
Workaround statistics function to time point survival estimate with CI
Description
This is a workaround for tern::s_surv_timepoint(), which adds a statistic
containing the time point specific survival estimate together with the
confidence interval.
Usage
a_event_free(
df,
.var,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
s_event_free(
df,
.var,
time_point,
time_unit,
is_event,
percent = FALSE,
control = control_surv_timepoint()
)
Arguments
df |
( |
.var |
( |
... |
additional arguments for the lower level functions. |
.stats |
( |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
time_point |
( |
time_unit |
( |
is_event |
( |
percent |
( |
control |
( |
Value
-
s_event_freereturns a list as returned by thetern::s_surv_timepoint()with an additional three-dimensional statisticevent_free_ciwhich combines theevent_free_rateandrate_cistatistics. -
a_event_freeis analogous to tern::a_surv_timepoint but with the additional three-dimensional statistic described above available via.stats.
Functions
-
a_event_free(): Formatted analysis function which is used asafun. -
s_event_free(): Statistics function which works liketern::s_surv_timepoint(), the difference is that it returns the additional statisticevent_free_ci.
Examples
adtte_f <- tern::tern_ex_adtte |>
dplyr::filter(PARAMCD == "OS") |>
dplyr::mutate(
AVAL = tern::day2month(AVAL),
is_event = CNSR == 0
)
basic_table() |>
split_cols_by(var = "ARMCD") |>
analyze(
vars = "AVAL",
afun = a_event_free,
show_labels = "hidden",
na_str = tern::default_na_str(),
extra_args = list(
time_unit = "week",
time_point = 3,
is_event = "is_event"
)
) |>
build_table(df = adtte_f)
adtte_f <- tern::tern_ex_adtte |>
dplyr::filter(PARAMCD == "OS") |>
dplyr::mutate(
AVAL = tern::day2month(AVAL),
is_event = CNSR == 0
)
s_event_free(
df = adtte_f,
.var = "AVAL",
time_point = 6,
is_event = "is_event",
time_unit = "month"
)
Export a TLG (Table, Listing, Graph) to .docx format
Description
Export a TLG (Table, Listing, Graph) to .docx format
Usage
export_TLG_as_docx(
obj = NULL,
tblid = NULL,
output_dir = NULL,
theme = theme_docx_default_j(font = "Times New Roman", font_size = 9L, bold = NULL),
add_page_break = FALSE,
titles_as_header = TRUE,
integrate_footers = TRUE,
section_properties = officer::prop_section(page_size = officer::page_size(width = 11,
height = 8.5, orient = orientation), page_margins = officer::page_mar(bottom = 1, top
= 1, right = 1, left = 1, gutter = 0, footer = 1, header = 1)),
doc_metadata = NULL,
template_file = NULL,
orientation = "portrait",
paginate = tlgtype == "Table",
nosplitin = list(row = character(), col = character()),
string_map = default_str_map,
markup_df_docx = dps_markup_df_docx,
combined_docx = FALSE,
tlgtype = ifelse(is.null(obj), "Figure", tlg_type(obj)),
col_gap = ifelse(tlgtype == "Listing", 0.5, 3),
pagenum = ifelse(tlgtype == "Listing", TRUE, FALSE),
round_type = ifelse(tlgtype %in% c("Table", "Listing"),
formatters::obj_round_type(obj), "iec"),
alignments = list(),
border = flextable::fp_border_default(width = 0.875, color = "black"),
border_mat = NULL,
export_csv = FALSE,
output_csv_directory = NULL,
markup_df = dps_markup_df,
validate = TRUE,
watermark = NULL,
plotnames = NULL,
title = NULL,
footers = NULL,
plotwidth = 8,
plotheight = 5.51,
units = c("in", "cm", "mm", "px")[1],
...
)
Arguments
obj |
( |
tblid |
( |
output_dir |
( |
theme |
(function factory) |
add_page_break |
( |
titles_as_header |
( |
integrate_footers |
( |
section_properties |
( |
doc_metadata |
(list of |
template_file |
( |
orientation |
( |
paginate |
( |
nosplitin |
( |
string_map |
( |
markup_df_docx |
( |
combined_docx |
( |
tlgtype |
( |
col_gap |
( |
pagenum |
( |
round_type |
( |
alignments |
( |
border |
( |
border_mat |
( |
export_csv |
( |
output_csv_directory |
( |
markup_df |
( |
validate |
( |
watermark |
( |
plotnames |
( |
title |
( |
footers |
( |
plotwidth |
( |
plotheight |
( |
units |
( |
... |
other parameters. |
Note
This function may be removed from junco in the future if the functionality
is merged into rtables.officer.
For more information, refer to the vignette table_and_listing_customizations
(browseVignettes("junco"))
Examples
adsl <- ex_adsl
adae <- ex_adae
extra_args_1 <- list(
.stats = c("count_unique_denom_fraction")
)
lyt1 <- basic_table(show_colcounts = TRUE) |>
split_cols_by("ARM") |>
analyze(
vars = "COUNTRY",
afun = a_freq_j,
extra_args = extra_args_1
)
tbl1 <- build_table(lyt1, adsl)
tab_titles <- list(
"title" = "This is the main Title",
"subtitles" = NULL,
"main_footer" = c(
"footer 1",
"footer 2"
),
"prov_footer" = NULL)
tbl1b <- set_titles(tbl1, tab_titles)
export_TLG_as_docx(
obj = tbl1b,
tblid = "test",
output_dir = tempdir(),
theme = theme_docx_default_j(), add_page_break = FALSE,
titles_as_header = TRUE, integrate_footers = TRUE,
section_properties = officer::prop_section(
page_size = officer::page_size(width = 11, height = 8.5, orient = "portrait"),
page_margins = officer::page_mar(
bottom = 1,
top = 1,
right = 1,
left = 1,
gutter = 0,
footer = 1,
header = 1)
),
doc_metadata = NULL,
template_file = NULL,
orientation = "portrait",
paginate = FALSE,
nosplitin = list(
row = character(),
col = character()
),
string_map = default_str_map,
markup_df_docx = junco:::dps_markup_df_docx,
combined_docx = FALSE,
tlgtype = "Table",
col_gap = 3,
pagenum = FALSE,
round_type = "iec",
alignments = list(),
border = flextable::fp_border_default(width = 0.875, color = "black"),
border_mat = NULL,
watermark = NULL,
plotnames = NULL,
title = NULL,
footers = NULL,
plotwidth = 8,
plotheight = 5.51,
units = "in"
)
Export a VTableTree or a listing_df object into docx
Description
This function is based on rtables.officer::export_as_docx().
Usage
export_as_docx_j(
tt,
tblid = NULL,
output_dir = NULL,
theme = theme_docx_default_j(font = "Times New Roman", font_size = 9L, bold = NULL),
add_page_break = FALSE,
titles_as_header = TRUE,
integrate_footers = TRUE,
section_properties = officer::prop_section(page_size = officer::page_size(width = 11,
height = 8.5, orient = orientation), page_margins = officer::page_mar(bottom = 1, top
= 1, right = 1, left = 1, gutter = 0, footer = 1, header = 1)),
doc_metadata = NULL,
template_file = NULL,
orientation = "portrait",
paginate = tlgtype == "Table",
nosplitin = list(row = character(), col = character()),
string_map = default_str_map,
markup_df_docx = dps_markup_df_docx,
combined_docx = FALSE,
tlgtype = tlg_type(tt),
col_gap = ifelse(tlgtype == "Listing", 0.5, 3),
pagenum = ifelse(tlgtype == "Listing", TRUE, FALSE),
round_type = formatters::obj_round_type(tt),
alignments = list(),
border = flextable::fp_border_default(width = 0.875, color = "black"),
border_mat = make_header_bordmat(obj = tt),
watermark = NULL,
export_csv = FALSE,
output_csv_directory = NULL,
markup_df = dps_markup_df,
validate = TRUE,
...
)
Arguments
tt |
( |
tblid |
( |
output_dir |
( |
theme |
(function factory) |
add_page_break |
( |
titles_as_header |
( |
integrate_footers |
( |
section_properties |
( |
doc_metadata |
(list of |
template_file |
( |
orientation |
( |
paginate |
( |
nosplitin |
( |
string_map |
( |
markup_df_docx |
( |
combined_docx |
( |
tlgtype |
( |
col_gap |
( |
pagenum |
( |
round_type |
( |
alignments |
( |
border |
( |
border_mat |
( |
watermark |
( |
export_csv |
( |
output_csv_directory |
( |
markup_df |
( |
validate |
( |
... |
other parameters. |
Note
This function may be removed from junco in the future if the functionality
is merged into rtables.officer.
For more information, refer to the vignette table_and_listing_customizations
(browseVignettes("junco"))
export_graph_as_docx
Description
Export graph in DOCX format.
Usage
export_graph_as_docx(
g = NULL,
plotnames = NULL,
tblid = NULL,
output_dir = NULL,
title = NULL,
footers = NULL,
orientation = "portrait",
plotwidth = 8,
plotheight = 5.51,
units = c("in", "cm", "mm", "px")[1],
border = flextable::fp_border_default(width = 0.875, color = "black"),
watermark = NULL
)
Arguments
g |
( |
plotnames |
( |
tblid |
( |
output_dir |
( |
title |
( |
footers |
( |
orientation |
( |
plotwidth |
( |
plotheight |
( |
units |
( |
border |
( |
watermark |
( |
Note
This function may be removed from junco in the future if the functionality
is merged into rtables.officer.
For more information, refer to the vignette table_and_listing_customizations
(browseVignettes("junco"))
Create a factor with levels ordered by a separate ordering vector
Description
Converts a character vector or factor into a factor where the level order is determined by a second integer-like vector containing the corresponding order values.
Usage
factor_by_order(x, y, ordered = FALSE)
Arguments
x |
( |
y |
( |
ordered |
( |
Details
The values in x and y must define a bijection between the unique
non-missing values: each unique value in x must correspond to exactly one
unique value in y, and vice versa.
Missing values are handled separately: NA values in x and y must
occur at the same positions. Missing values are not included as factor
levels.
If x is already a factor containing unobserved (unused) levels, these
unobserved levels will be dropped in the resulting factor.
Value
A factor created from x, with levels ordered according to y.
Attributes of x other than class and levels are preserved.
If ordered = TRUE, an ordered factor is returned.
If x is empty or consists entirely of missing values, a factor with
no levels is returned.
Author(s)
WW
Examples
factor_by_order(c("A", "A", "B"), c(1, 1, 2))
factor_by_order(c("A", "A", "B"), c(1, 1, 2), ordered = TRUE)
factor_by_order(c("A", "A", "B"), c(2, 2, 1))
factor_by_order(c("A", "A", "B", NA), c(1, 1, 2, NA))
## Not run:
factor_by_order(c("A", "A", "B", NA), c(1, 2, 2, 4))
## End(Not run)
Helper for Finding AVISIT after which CHG are all Missing
Description
Helper for Finding AVISIT after which CHG are all Missing.
Usage
find_missing_chg_after_avisit(df)
Arguments
df |
( |
Value
A string with either the factor level after which AVISIT is all missing,
or NA.
Examples
df <- data.frame(
AVISIT = factor(c(1, 2, 3, 4, 5)),
CHG = c(5, NA, NA, NA, 3)
)
find_missing_chg_after_avisit(df)
df2 <- data.frame(
AVISIT = factor(c(1, 2, 3, 4, 5)),
CHG = c(5, NA, 3, NA, NA)
)
find_missing_chg_after_avisit(df2)
df3 <- data.frame(
AVISIT = factor(c(1, 2, 3, 4, 5)),
CHG = c(NA, NA, NA, NA, NA)
)
find_missing_chg_after_avisit(df3)
ANCOVA Analysis
Description
Performs the ANCOVA analysis, separately for each visit.
Usage
fit_ancova(
vars = list(response = "AVAL", covariates = c(), arm = "ARM", visit = "AVISIT", id =
"USUBJID"),
data,
conf_level = 0.95,
weights_emmeans = "proportional"
)
Arguments
vars |
(named
Note that the |
data |
( |
conf_level |
( |
weights_emmeans |
( |
Value
A tern_model object which is a list with model results:
-
fit: A list with a fittedstats::lm()result for each visit. -
mse: Mean squared error, i.e. variance estimate, for each visit. -
df: Degrees of freedom for the variance estimate for each visit. -
lsmeans: This is a list with data framesestimatesandcontrasts. The attributeweightssavse the settings used (weights_emmeans). -
vars: The variable list. -
labels: Corresponding list with variable labels extracted fromdata. -
ref_level: The reference level for the arm variable, which is always the first level. -
treatment_levels: The treatment levels for the arm variable. -
conf_level: The confidence level which was used to construct thelsmeansconfidence intervals.
Examples
library(mmrm)
fit <- fit_ancova(
vars = list(
response = "FEV1",
covariates = c("RACE", "SEX"),
arm = "ARMCD",
id = "USUBJID",
visit = "AVISIT"
),
data = fev_data,
conf_level = 0.9,
weights_emmeans = "equal"
)
MMRM Analysis
Description
Does the MMRM analysis. Multiple other functions can be called on the result to produce
tables and graphs.
Usage
fit_mmrm_j(
vars = list(response = "AVAL", covariates = c(), id = "USUBJID", arm = "ARM", visit =
"AVISIT", subgroup = NULL),
data,
conf_level = 0.95,
cor_struct = "unstructured",
weights_emmeans = "counterfactual",
averages_emmeans = list(),
mult_adj_emmeans = c("none", "dunnett", "step-down-dunnett"),
...
)
Arguments
vars |
(named
Note that the main effects and interaction of |
data |
( |
conf_level |
( |
cor_struct |
( |
weights_emmeans |
( |
averages_emmeans |
( |
mult_adj_emmeans |
( |
... |
additional arguments for |
Details
Multiple different degree of freedom adjustments are available via the method argument
for mmrm::mmrm(). In addition, covariance matrix adjustments are available via vcov.
Please see mmrm::mmrm_control() for details and additional useful options.
For the covariance structure (cor_struct), the user can choose among the following options.
-
unstructured: Unstructured covariance matrix. This is the most flexible choice and default. If there areTvisits, thenT * (T+1) / 2variance parameters are used. -
toeplitz: Homogeneous Toeplitz covariance matrix, which usesTvariance parameters. -
heterogeneous toeplitz: Heterogeneous Toeplitz covariance matrix, which uses2 * T - 1variance parameters. -
ante-dependence: Homogeneous Ante-Dependence covariance matrix, which usesTvariance parameters. -
heterogeneous ante-dependence: Heterogeneous Ante-Dependence covariance matrix, which uses2 * T - 1variance parameters. -
auto-regressive: Homogeneous Auto-Regressive (order 1) covariance matrix, which uses 2 variance parameters. -
heterogeneous auto-regressive: Heterogeneous Auto-Regressive (order 1) covariance matrix, which usesT + 1variance parameters. -
compound symmetry: Homogeneous Compound Symmetry covariance matrix, which uses 2 variance parameters. -
heterogeneous compound symmetry: Heterogeneous Compound Symmetry covariance matrix, which usesT + 1variance parameters.
Value
A tern_model object which is a list with model results:
-
fit: Themmrmobject which was fitted to the data. Note that viammrm::component(fit, 'optimizer')the finally used optimization algorithm can be obtained, which can be useful for refitting the model later on. -
cov_estimate: The matrix with the covariance matrix estimate. -
diagnostics: A list with model diagnostic statistics (REML criterion, AIC, corrected AIC, BIC). -
lsmeans: This is a list with data framesestimatesandcontrasts. The attributesaverages,weightsandmult_adjsave the settings used (averages_emmeans,weights_emmeansandmult_adj_emmeans). -
vars: The variable list. -
labels: Corresponding list with variable labels extracted fromdata. -
cor_struct: input. -
ref_level: The reference level for the arm variable, which is always the first level. -
treatment_levels: The treatment levels for the arm variable. -
conf_level: The confidence level which was used to construct thelsmeansconfidence intervals. -
additional: List with any additional inputs passed via...
Note
This function has the _j suffix to distinguish it from mmrm::fit_mmrm().
It is modified from the tern.mmrm package.
The new features are:
the
mult_adj_emmeansargument and its functionalitythe
subgroupvariable invarsand its functionality
These could later be contributed upstream in tern.mmrm.
Examples
mmrm_results <- fit_mmrm_j(
vars = list(
response = "FEV1",
covariates = c("RACE", "SEX"),
id = "USUBJID",
arm = "ARMCD",
visit = "AVISIT"
),
data = mmrm::fev_data,
cor_struct = "unstructured",
weights_emmeans = "equal",
averages_emmeans = list(
"VIS1+2" = c("VIS1", "VIS2")
)
)
Utilities for processing d-style string formatting specifications (eg "xx.dx")
Description
Usage
fmt_spec_single_d(
d = 1,
stats_in = NULL,
fmt_d_def = junco_def_d_all,
fmt_d_in = NULL
)
fmt_spec_df_d(
df_d,
d_column = "d",
fmt_column = "fmt_d",
stats_in = NULL,
fmt_d_def = junco_def_d_all,
fmt_d_in = NULL
)
fmt_spec_var_d(
var_d,
stats_in = NULL,
fmt_d_def = junco_def_d_all,
fmt_d_in = NULL
)
junco_def_d_all
junco_def_d_alt1
junco_def_d_alt2
Arguments
d |
|
stats_in |
|
fmt_d_def |
Named vector with default format specifications where d-style format is allowed. |
fmt_d_in |
Named vector with format specifications where d-style format is allowed.
Formats defined here will take higher precedence over formats in |
df_d |
Dataframe in which the d-column specification is available. |
d_column |
Name of column within dataframe |
fmt_column |
Name of column that will be added to dataframe that will contain resulting format specifications. |
var_d |
Named vector of d specifications. Names are to be considered as variables to be analyzed in further processing. |
Format
-
junco_def_d_allUsed as default input vector for argumentfmt_d_defin functionsfmt_spec_single_d(),fmt_spec_df_d()andfmt_spec_var_d()(corresponds to the named vector of with default available formats junco_default_formats with d = 1)
-
junco_def_d_alt1Alternative vector of d-style specification defaults.
-
junco_def_d_alt2Another alternative vector of d-style specification defaults.
Details
Format specifications in d-style notation (such as "xx.dx")
will be translated to string based formats
(or wrapped with jjcsformat_xx()), eg "xx.dx" will be translated into "xx.xx", when d = 1.
Functions
-
fmt_spec_single_d(): Function to convert a named list using d-style string format specification into a named list with validformattersformatting specification -
fmt_spec_df_d(): Function to convert an input column with d-style formatting specification into a new column with valid formatters formatting specification.The new column can be passed onto argument
formats_varinrtables::analyze()function. -
fmt_spec_var_d(): Function to convert a named list of variables with d-style formatting specification into a named list with validformattersformatting specification.The result can be used as input for argument
formatinrtables::analyze()call. -
junco_def_d_all: Named vector of default format specification using d-style notation. -
junco_def_d_alt1: Alternative vector of d-style specification defaults. -
junco_def_d_alt2: Another alternative vector of d-style specification defaults.
Examples
junco_def_d <- c(
"mean" = "xx.dx",
"mean_sd" = "xx.dx (xx.dxx)",
"mean_se" = "xx.dx (xx.dxx)",
"range" = "(xx.d, xx.d)"
)
myfmts <- fmt_spec_single_d(
d = 1,
stats_in = c("mean", "mean_sd"),
fmt_d_def = junco_def_d,
fmt_d_in = NULL
)
myfmts
# example for fmt_spec_df_d ----
library(dplyr)
df_d <- tribble(
~PARAMCD, ~d,
"DIABP", 2L,
"PULSE", 3L,
"RESP", 1L
)
yy <- fmt_spec_df_d(df_d,
d_column = "d",
fmt_column = "fmt_d",
stats_in = NULL,
fmt_d_def = junco_def_d,
fmt_d_in = NULL
)
df <- ex_advs |>
filter(PARAMCD %in% c("DIABP", "PULSE", "RESP")) |>
filter(AVISIT %in% c("BASELINE", "WEEK 1 DAY 8", "WEEK 2 DAY 15"))
df <- df |>
left_join(yy)
lyt <- basic_table() |>
split_cols_by("ARMCD") |>
split_rows_by("PARAMCD", split_fun = drop_split_levels) |>
split_rows_by("AVISIT", split_fun = drop_split_levels) |>
analyze(
vars = "AVAL",
afun = tern::a_summary,
extra_args = list(
.stats = c("n", "mean_se", "range"),
.formats = "default"
),
formats_var = "fmt_d"
)
rslt <- build_table(lyt, df, alt_counts_df = ex_adsl)
rslt
# example for fmt_spec_var_d ----
var <- c("AGE" = 0, "BMI" = 1, "BMRKR1" = 2)
vars_fmt <- fmt_spec_var_d(var,
stats_in = NULL,
fmt_d_def = junco_def_d,
fmt_d_in = NULL
)
vars_fmt
lyt <- basic_table() |>
split_cols_by("ARMCD") |>
analyze(
vars = c("AGE", "BMRKR1"),
afun = tern::a_summary,
extra_args = list(
.stats = c("n", "mean_sd", "range"),
.formats = "default"
),
format = vars_fmt,
section_div = " "
)
rslt <- build_table(lyt, ex_adsl)
rslt
Utilities for reviewing format specification objects
Description
Usage
get_fmt_details(myfmts, recursive = FALSE, as_tibble = TRUE)
compare_fmt_specs(fmt1, fmt2)
Arguments
myfmts |
A named list of either formatting specifications (ie stats with its associated formats) or a list of variables with formatting specifications. |
recursive |
|
as_tibble |
|
fmt1 |
A named list of formatting specifications (ie stats with its associated format) |
fmt2 |
Another named list of formatting specifications (ie stats with its associated format),
to compare against |
Details
fmt_utils general details
Functions
-
get_fmt_details(): A utility function to collect information on formatting specification in list or tibble format.The following information is collected:
var (variable name): Only applicable if the format specification is a named list with formattings specs (eg list("AGE" = c("mean" = "xx", "se" = "xx.x"), "BMI" = c("mean" = "xx.x", "se" = "xx.xx"))), eg processed via
fmt_spec_var_dfunction.stat (name of statistic)
fun_fact : name of function factory that has produced the format specification (if spec is from formatting function, blank if spec is string).
Only the following known formatting functions are supported:jjcsformat_xx
jjcsformat_cnt_den_fract_fct,
jjcsformat_pval_fct,
jjcsformat_range_fct,
tern::format_xx,
tern::format_extreme_values,
tern::format_extreme_values_ci,
tern::format_count_fraction_fixed_dp,
tern::format_count_fraction,
tern::format_fraction_fixed_dp,
format_sigfig_j
str: string from specification, or str from formatting function factory (
jjcsformat_xx, ....)str_formatters: (
logical) Is the str value a valid format string as in (list_valid_format_labels())?type: when formatting function factory
jjcsformat_cnt_den_fract_fctis usedalpha: when formatting function factory
jjcsformat_pval_fctis usedmessage: Message when formatting function is unknown, or input string was not valid format string as in (
list_valid_format_labels())fmt_package: In which package was the formatting specification defined.
is_fun: (
logical) Is the formatting specification a function?round_type: (
logical) Does the formatting supportround_typeargument/behavior?fun: Formatting string or body of the formatting function.
Only when one of the formats provided is based upon formatting function factory
format_sigfig_jsetup:d: value used for
sigfigwhole_integer: value used for
whole_integerdrop0trailing: value used for
drop0trailingzero_threshold: value used for
zero_threshold
-
compare_fmt_specs(): A utility to report findings in differences between 2 formatting specification vectors. It returns a list object with the following information:spec1 : For statistics with a different specification, tibble with specification details from
fmt1.spec2 : For statistics with a different specification, tibble with specification details from
fmt2. The tibbles inspec1andspec2contain information as described inget_fmt_details().msg: Message on how many stats have a difference in specification.
comm_stats: Vector of stats in common between
fmt1andfmt2.diff_stats: Vector of stats with any difference identified.
Examples
# Example for get_fmt_details --
junco_def_d <- c(
"mean" = "xx.dx",
"mean_sd" = "xx.dx (xx.dxx)",
"range" = "(xx.d, xx.d)"
)
myfmts <- fmt_spec_single_d(
d = 1,
stats_in = c("mean", "mean_sd"),
fmt_d_def = junco_def_d,
fmt_d_in = NULL
)
fmt_details <- get_fmt_details(myfmts, as_tibble = TRUE)
myfmts2 <- fmt_spec_single_d(
d = 3,
stats_in = c("mean", "mean_sd"),
fmt_d_def = junco_def_d,
fmt_d_in = NULL
)
fmt_details2 <- get_fmt_details(myfmts2, as_tibble = TRUE)
fmt_details2
# Example for get_fmt_details using format specs for variables --
# processed with fmt_spec_var_d
var <- c("AGE" = 0, "BMI" = 1, "BMRKR1" = 2)
vars_fmt <- fmt_spec_var_d(var,
stats_in = NULL,
fmt_d_def = junco_def_d,
fmt_d_in = NULL
)
fmt_details2 <- get_fmt_details(vars_fmt, as_tibble = TRUE, recursive = TRUE)
# Example for compare_fmt_specs --
test1_target <- junco_default_formats
# junco_def_d_all has been constructed with d = 1 as reference
# compare against junco_default_formats
test1_d <- fmt_spec_single_d(
d = 1,
stats_in = NULL,
fmt_d_def = junco_def_d_all,
fmt_d_in = NULL
)
check1 <- compare_fmt_specs(test1_d, test1_target)
check1
# more differences when using other d
test2_d <- fmt_spec_single_d(
d = 2,
stats_in = NULL,
fmt_d_def = junco_def_d_all,
fmt_d_in = NULL
)
check2 <- compare_fmt_specs(test2_d, test1_target)
Format numeric values by significant figures.
Description
Format numeric values by significant figures with controllable round_type,
whole_integer and trailing zeros.
The underlying function for significant figures is modified_signif_j(), which is a modified version for
base::signif()
Usage
format_sigfig_j(
sigfig,
format = "xx",
whole_integer = TRUE,
zero_threshold = 10^(-2 * sigfig),
drop0trailing = FALSE
)
modified_signif_j(
x,
digits = 6,
round_type = valid_round_type,
whole_integer = FALSE,
zero_threshold = 0
)
Arguments
sigfig |
( |
format |
( |
whole_integer |
( |
zero_threshold |
( |
drop0trailing |
( |
x |
( |
digits |
( |
round_type |
( |
Value
A formatting function with signature function(x, round_type, ...) that
returns a formatted string. The round_type argument accepts rounding methods
("iec", "iec_mod", "sas") (see formatters::round_fmt()).
Functions
-
format_sigfig_j(): A function factory that produces formatting functions to round values to a specified number of significant figures, suitable for use withformatters::format_value().
The function is an alternative totern::format_sigfig(),format_sigfig_j()has fixed theformatCargumentnum_fmt = "fg", and has extra options forwhole_integeranddrop0trailingto control the format behavior. -
modified_signif_j(): A modified version of base function base::signif with 3 extensions:Rounding is performed using
formatters::round_fmt(), and allows for round types ("iec", "iec_mod", "sas")
Very small absolute values can be treated as zero (
zero_threshold).
All significant figures to the left of the decimal marker can be shown (whole_integer), rather than limiting the result to the specified number of significant figures.
Returns a numeric vector of the same length as
x, rounded todigitssignificant figures.
See Also
Examples
fmt <- format_sigfig_j(3)
fmt(0.001234)
fmt(1234.5)
fmt2 <- format_sigfig_j(3, format = "xx (xx)")
fmt2(c(1234.5, 0.00567))
format_sigfig_j(3, drop0trailing = FALSE)(0.01)
format_sigfig_j(3, drop0trailing = TRUE)(0.01)
# example code
junco:::modified_signif_j(c(0.1, 1e-9, 1256.0, 1256.5, 1256.3, 1254.5, 1256.5),
digits = 3,
zero_threshold = 0,
whole_integer = TRUE,
round_type = "sas"
)
junco:::modified_signif_j(c(0.1, 1e-9, 1256.0, 1256.5, 1256.3, 1254.5, 1256.5),
digits = 3,
zero_threshold = 1e-6,
whole_integer = TRUE,
round_type = "sas"
)
Get Control Subset
Description
Retrieves a subset of the DataFrame based on treatment variable and control group.
Usage
get_ctrl_subset(df, trt_var, ctrl_grp)
Arguments
df |
( |
trt_var |
( |
ctrl_grp |
( |
Value
Subset of the data frame.
Extract Least Square Means from MMRM
Description
Extracts the least square means from an MMRM fit.
Usage
get_mmrm_lsmeans(
fit,
vars,
conf_level,
weights,
averages = list(),
mult_adj = c("none", "dunnett", "step-down-dunnett")
)
Arguments
fit |
( |
vars |
(named
Note that the main effects and interaction of |
conf_level |
( |
weights |
( |
averages |
( |
mult_adj |
( |
Value
A list with data frames estimates and contrasts.
The attributes averages, weights and mult_adj save the settings used.
Note
This is modified from tern.mmrm and has the additional mult_adj argument.
Obtain reference group information from split context.
Description
get_ref_info() identifies a reference group defined by a column-split
path and returns both the reference-group data and an indicator of whether
the current column is the reference column. It is intended for use inside
custom rtables analysis functions.
The reference group is specified using ref_path, which consists of
alternating column-split variable names and its corresponding levels.
For example, c("SEX", "F", "ARM", "Placebo") specifies the column-split
path where SEX is "F" and ARM is "Placebo".
Usage
get_ref_info(ref_path, .spl_context, .var = NULL)
Arguments
ref_path |
( |
.spl_context |
( |
.var |
( |
Value
A list with the following elements:
-
in_ref_col(logical(1)orNULL) indicates whether the current column matches the reference path. This corresponds to.in_ref_colin rtables::additional_fun_params. -
ref_group(data.frame, vector, orNULL) contains the observations belonging to the reference group. If.varisNULL, the complete data frame is returned; otherwise, the column specified by.varis returned. This corresponds to.ref_groupin rtables::additional_fun_params.
If the reference path is not present in the current column-split
hierarchy, both elements are NULL.
Examples
dm <- DM
dm$colspan_trt <- factor(
ifelse(dm$ARM == "B: Placebo", " ", "Active Study Agent"),
levels = c("Active Study Agent", " ")
)
colspan_trt_map <- create_colspan_map(
dm,
non_active_grp = "B: Placebo",
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = "ARM"
)
# A standard analysis function which uses a reference group.
standard_afun <- function(x, .ref_group, .in_ref_col) {
diff_means <- if (isFALSE(.in_ref_col)) {
mean(x) - mean(.ref_group)
} else {
NULL
}
in_rows(
m = rcell(mean(x), label = "Mean"),
dm = rcell(diff_means, label = "Difference in Means vs Placebo"),
.formats = "xx.xx"
)
}
# The custom analysis function which can work with a global reference group.
result_afun <- function(x, ref_path, .spl_context, .var) {
ref <- get_ref_info(ref_path, .spl_context, .var)
standard_afun(x, .ref_group = ref$ref_group, .in_ref_col = ref$in_ref_col)
}
ref_path <- c("colspan_trt", " ", "ARM", "B: Placebo")
lyt <- basic_table() |>
split_cols_by("colspan_trt", split_fun = trim_levels_to_map(colspan_trt_map)) |>
split_cols_by("ARM") |>
add_overall_col("Total") |>
analyze("AGE", afun = result_afun, extra_args = list(ref_path = ref_path))
build_table(lyt, dm)
Get Titles/Footers For Table From Sources
Description
Retrieves the titles and footnotes for a given table from a CSV/XLSX file or a data.frame.
Usage
get_titles_from_file(
id,
file = .find_titles_file(input_path),
input_path = ".",
title_df = .read_titles_file(file)
)
Arguments
id |
( |
file |
( |
input_path |
( |
title_df |
( |
Details
Retrieves the titles for a given output id (see below) and outputs
a list containing the title and footnote objects supported by
rtables. Both titles.csv and titles.xlsx (if readxl is
installed) files are supported, with titles.csv being checked
first.
Data is expected to have `TABLE ID`, `IDENTIFIER`, and `TEXT` columns,
where `IDENTIFIER` has the value `TITLE` for a title and `FOOT*` for
footer materials where `*` is a positive integer. `TEXT` contains
the value of the title/footer to be applied.
Value
List object containing: title, subtitles, main_footer, prov_footer
for the table of interest. Note: the subtitles and prov_footer are
currently set to NULL. Suitable for use with set_titles().
Get Visit Levels in Order Defined by Numeric Version
Description
Get Visit Levels in Order Defined by Numeric Version
Usage
get_visit_levels(visit_cat, visit_n)
Arguments
visit_cat |
( |
visit_n |
( |
Value
The unique visit levels in the order defined by the numeric version.
Examples
get_visit_levels(
visit_cat = c("Week 1", "Week 11", "Week 2"),
visit_n = c(1, 5, 2)
)
Standard Column Structure With Grouped Treatments and Difference Columns
Description
Standard Column Structure With Grouped Treatments and Difference Columns
Usage
grouped_cols_w_diffs(
lyt,
colspan_trt_map,
combo_map_df = NULL,
comp_map = NULL,
diff_cols = TRUE,
diffs_label = "Risk Differences",
.main_pre = list(),
.main_post = list(),
.rr_pre = list(),
.rr_post = list()
)
grouped_cols_w_subgrps(
lyt,
colspan_trt_map = NULL,
combo_map_df = NULL,
trtvar = names(colspan_trt_map)[2],
subgrp_var = NULL,
subgrp_lbl = subgrp_var,
total_facet = TRUE,
total_lbl = "Total",
.pre = list(),
.post = list()
)
Arguments
lyt |
( |
colspan_trt_map |
( |
combo_map_df |
( |
comp_map |
( |
diff_cols |
( |
diffs_label |
( |
.main_pre |
( |
.main_post |
( |
.rr_pre |
( |
.rr_post |
( |
trtvar |
( |
subgrp_var |
( |
subgrp_lbl |
( |
total_facet |
( |
total_lbl |
( |
.pre |
( |
.post |
( |
Details
This function combines multiple rtables column splitting
instructions with customized split functions to create a column
structure with treatment columns for each treatment arm (optionally
including combination arms), grouped by active and non-active, with
risk difference columns comparing active arm(s) against one or more
non-active controls. It is intended for use in layouts that will
use a_freq_j() or similar junco-style analysis functions which
support risk difference columns and accept a ref_path argument.
It is equivalent to the following sequence of layout instructions:
splitting on a colspan labeling variable with
rtables::trim_levels_to_map()as the split function;splitting on treatment;
adding a (non-nested) overall column acting as the risk difference spanning label; and finally
splitting on treatment using
make_multicomp_splfun()as the split function
In addition, it supports:
comparison against multiple control groups (as specified by
colspan_trt_mapand/orcomp_map),virtual combination-levels as active an/or control "treatments" (via
combo_map_df),full control of which comparisons are performed, and their order (via
comp_map).
If combination levels are declared via combo_map_df but none
appear in colspan_trt_map, all combinations will be added to the
appropriate group within the map based on combo_map_df$is_control
(assumed to be FALSE if the column is missing), with a warning.
If some combination levels do appear in combo_map_df but
others do not, a warning will be thrown but the missing combination
levels will not be added to the treatment map.
By default (when comp_map is NULL), all active treatments,
including active combinations, will be compared against all control
groups.
The risk difference section of the structure is declared using
make_multicomp_splfun(). Reference paths are inferred
automatically from colspan_trt_map (after combination levels have
been added if necessary).
For the purposes of pathin in the resulting structure,
diffs_label will be both the split name and split value of the
parent containing the individual risk difference columns.
grouped_cols_w_subgrps creates a hierarchical column
structure that splits by trtvar, underneath which is a
spanning label over a split with a Total column along with
columns for each level of subgrp_var.
Value
lyt updated with the specified main and risk difference
column structures added
See Also
Other std_col_struct:
make_multicomp_splfun(),
shift_tbl_col_struct()
Examples
colspan_var <- create_colspan_var(
data.frame(TRT01A = factor(c("Placebo", "Active 1", "Active 2"))),
non_active_grp = "Placebo",
non_active_grp_span_lbl = "Control",
active_grp_span_lbl = "Active Treatment",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
colspan_trt_map <- create_colspan_map(
colspan_var,
non_active_grp = "Placebo",
non_active_grp_span_lbl = "Control",
active_grp_span_lbl = "Active Treatment",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
lyt <- basic_table() |>
grouped_cols_w_diffs(colspan_trt_map) |>
analyze("TRT01A", afun = function(x, ...) length(x))
build_table(lyt, colspan_var)
dat <- create_colspan_var(
data.frame(
TRT01A = factor(rep(c("Placebo", "Active 1"), each = 2)),
SEX = factor(rep(c("Female", "Male"), 2))
),
non_active_grp = "Placebo",
non_active_grp_span_lbl = "Control",
active_grp_span_lbl = "Active Treatment",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
colspan_trt_map <- create_colspan_map(
dat,
non_active_grp = "Placebo",
non_active_grp_span_lbl = "Control",
active_grp_span_lbl = "Active Treatment",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
lyt <- basic_table() |>
grouped_cols_w_subgrps(
colspan_trt_map,
subgrp_var = "SEX",
subgrp_lbl = "SUB_*"
) |>
analyze("TRT01A", afun = function(x, ...) length(x))
build_table(lyt, dat)
Extract Estimates from Multivariate Cox Regression Model Fit Object
Description
Extract Estimates from Multivariate Cox Regression Model Fit Object
Usage
h_extract_coxreg_multivar(x)
Arguments
x |
( |
Value
A data frame containing Cox regression results with columns for term, coef_se (coefficient and standard error), p.value, hr (hazard ratio), hr_ci (confidence interval for hazard ratio), and labels (formatted term labels).
Examples
anl <- tern::tern_ex_adtte |>
dplyr::mutate(EVENT = 1 - CNSR)
variables <- list(
time = "AVAL",
event = "EVENT",
arm = "ARM",
covariates = c("SEX", "AGE")
)
control <- tern::control_coxreg(
conf_level = 0.9,
ties = "efron"
)
fit <- tern::fit_coxreg_multivar(
data = anl,
variables = variables,
control = control
)
h_extract_coxreg_multivar(fit)
Extraction of Covariate Parts from Character Vector
Description
Extraction of Covariate Parts from Character Vector.
Usage
h_get_covariate_parts(covariates)
Arguments
covariates |
( |
Value
Character vector of the covariates involved in covariates specification.
Get Current Treatment Group
Description
Retrieves the current treatment group from the current column split-path, given the treatment variable name.
Usage
h_get_cur_trt_grp(trt_var, .spl_context)
Arguments
trt_var |
( |
.spl_context |
( |
Value
A character string containing the treatment group name.
Author(s)
WW
See Also
Examples
## Not run:
.spl_context <- data.frame(
cur_col_split = I(list(c("ARM"))),
cur_col_split_val = I(list(c("Placebo")))
)
h_get_cur_trt_grp("ARM", .spl_context)
h_get_cur_trt_grp("TRT", .spl_context) # errors: TRT not found
## End(Not run)
Helper Function to Create Logical Design Matrix from Factor Variable
Description
Helper Function to Create Logical Design Matrix from Factor Variable.
Usage
h_get_design_mat(df, .var)
Arguments
df |
( |
.var |
( |
Value
The logical matrix with dummy encoding of all factor levels.
Examples
h_get_design_mat(df = data.frame(a = factor(c("a", "b", "a"))), .var = "a")
Helper Function to Extract Count Responders
Description
Converts a response vector, or a response column from a data frame, to logical values and returns its responder and observation counts.
Usage
h_get_rsp_counts(x, .var, na.rm = FALSE)
Arguments
x |
( |
.var |
( |
na.rm |
( |
Value
A named list with rsp (logical response vector), n_rsp (responders) and len_rsp
(non-missing observations, when na.rm = TRUE).
Impute missing binary responses and analyze each imputed data set
Description
Performs independent Bernoulli imputations for missing binary responses in
the control and treatment groups, then calculates a CMH risk difference and
p-value for each imputed data set. Only observations in ctrlab and
trtlab are included in the analysis.
Usage
h_impute_analyze_resp(
dat,
p_ctrl,
p_trt,
trtvar,
ctrlab,
trtlab,
respvar,
stratvar,
n_imputations
)
Arguments
dat |
( |
p_ctrl |
( |
p_trt |
( |
trtvar |
( |
ctrlab |
( |
trtlab |
( |
respvar |
( |
stratvar |
( |
n_imputations |
( |
Value
A tibble with one row per imputation and the following columns:
-
rd_est: CMH risk-difference estimate. -
rd_se: standard error of the risk-difference estimate. -
rd_var: variance of the risk-difference estimate. -
p_cmh: CMH p-value using the Wilson-Hilferty transformation. -
z_stat: Wilson-Hilferty z statistic used to calculatep_cmh.
Helper function to normalize p-value categories
Description
Converts a named list of p-value category bounds into a matrix and retains the category labels in their supplied order.
Usage
h_normalize_pvalcat(pvalcat)
Arguments
pvalcat |
( |
Value
A named list with the following elements:
-
bounds: a two-column numeric matrix of lower and upper category bounds. -
cats: a character vector of category labels.
Helper functions for odds ratio estimation
Description
Functions to calculate odds ratios in s_odds_ratio_j().
Usage
or_glm_j(data, conf_level)
or_clogit_j(data, conf_level, method = "exact")
or_cmh(data, conf_level)
Arguments
data |
( |
conf_level |
( |
method |
( |
Value
A named list of elements or_ci, n_tot and pval.
Functions
-
or_glm_j(): Estimates the odds ratio based onstats::glm(). Note that there must be exactly 2 groups indataas specified by thegrpvariable. -
or_clogit_j(): Estimates the odds ratio based onsurvival::clogit(). This is done for the whole data set including all groups, since the results are not the same as when doing pairwise comparisons between the groups. -
or_cmh(): Estimates the odds ratio based on CMH. Note that there must be exactly 2 groups indataas specified by thegrpvariable.
See Also
Examples
data <- data.frame(
rsp = as.logical(c(1, 1, 0, 1, 0, 0, 1, 1)),
grp = letters[c(1, 1, 1, 2, 2, 2, 1, 2)],
strata = letters[c(1, 2, 1, 2, 2, 2, 1, 2)],
stringsAsFactors = TRUE
)
or_glm_j(data, conf_level = 0.95)
data <- data.frame(
rsp = as.logical(c(1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0)),
grp = letters[c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3)],
strata = LETTERS[c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2)],
stringsAsFactors = TRUE
)
or_clogit_j(data, conf_level = 0.95)
set.seed(123)
data <- data.frame(
rsp = as.logical(rbinom(n = 40, size = 1, prob = 0.5)),
grp = letters[sample(1:2, size = 40, replace = TRUE)],
strata = LETTERS[sample(1:2, size = 40, replace = TRUE)],
stringsAsFactors = TRUE
)
or_cmh(data, conf_level = 0.95)
Helper function to set labels for s_proportion_diff_mf() statistics
Description
Sets descriptive labels on the statistics returned by s_proportion_diff_mf().
The label includes the detailed names of the two methods that may be selected
according to the Mantel-Fleiss criterion: mf_method is selected when the
criterion is satisfied, while non_mf_method is selected when the criterion
is not satisfied or cannot be evaluated.
Specifically, the method part of the label has the form
"(mf_method_label / non_mf_method_label)", where mf_method_label and
non_mf_method_label are the corresponding detailed method names.
Usage
h_set_labels_prop_diff_mf(
y,
mf_method,
non_mf_method = "uncond_exact_diff",
conf_level
)
Arguments
y |
( |
mf_method |
( |
non_mf_method |
( |
conf_level |
( |
Value
The input y with descriptive label attributes added to the "diff",
"diff_ci", and "diff_est_ci" elements.
Helper Function to Fit the MMRM and Return LS Mean Estimates and Contrasts
Description
Helper Function to Fit the MMRM and Return LS Mean Estimates and Contrasts
Usage
h_summarize_mmrm(
.var,
df_parent,
variables,
ref_arm_level,
ref_visit_levels,
...
)
Arguments
.var |
( |
df_parent |
( |
variables |
(named |
ref_arm_level |
( |
ref_visit_levels |
( |
... |
additional options passed to |
Value
The resulting estimates and contrasts LS means as returned by
tidy.tern_model().
Conversion of inches to spaces.
Description
Conversion of inches to spaces.
Usage
inches_to_spaces(ins, fontspec, raw = FALSE, tol = sqrt(.Machine$double.eps))
Arguments
ins |
( |
fontspec |
( |
raw |
( |
tol |
( |
Value
The number of either fractional (raw = TRUE) or whole (raw = FALSE)
spaces that will fit within ins inches in the specified font.
Insertion of Blank Lines in a Layout
Description
This is a hack for rtables in order to be able to add row gaps,
i.e. blank lines.
In particular, by default this function needs to maintain a global state for avoiding
duplicate table names. The global state variable is hidden by using
a dot in front of its name. However, this likely won't work with parallelisation across
multiple threads and also causes non-reproducibility of the resulting rtables
object. Therefore also a custom table name can be used.
Usage
insert_blank_line(lyt, table_names = NULL)
Arguments
lyt |
( |
table_names |
( |
Value
The modified layout now including a blank line after the current row content.
Examples
ADSL <- ex_adsl
lyt <- basic_table() |>
split_cols_by("ARM") |>
split_rows_by("STRATA1") |>
analyze(vars = "AGE", afun = function(x) {
in_rows(
"Mean (sd)" = rcell(c(mean(x), sd(x)), format = "xx.xx (xx.xx)")
)
}) |>
insert_blank_line() |>
analyze(vars = "AGE", table_names = "AGE_Range", afun = function(x) {
in_rows(
"Range" = rcell(range(x), format = "xx.xx - xx.xx")
)
})
build_table(lyt, ADSL)
Complex Scoring Function
Description
A function used for sorting AE tables (and others) as required.
Usage
jj_complex_scorefun(
spanningheadercolvar = "colspan_trt",
usefirstcol = FALSE,
colpath = NULL,
firstcat = NULL,
lastcat = NULL,
cellvalue_index = 1
)
Arguments
spanningheadercolvar |
( |
usefirstcol |
( |
colpath |
( |
firstcat |
( |
lastcat |
( |
cellvalue_index |
( |
Details
This sort function sorts as follows:
Takes all the columns from a specified spanning column header (default= colspan_trt) and sorts by the last treatment column within this.
If no spanning column header variable exists (e.g you have only one active treatment arm and have decided to remove the spanning header from your layout), it will sort by the first treatment column in your table.
This function is not really designed for tables that have sub-columns. However, if users wish to override any default sorting behavior, they can simply specify their own colpath to use for sorting on (default = NULL)
Value
A function which can be used as a score function (scorefun in sort_at_path).
Examples
library(dplyr)
ADAE <- data.frame(
USUBJID = c(
"XXXXX01", "XXXXX02", "XXXXX03", "XXXXX04", "XXXXX05",
"XXXXX06", "XXXXX07", "XXXXX08", "XXXXX09", "XXXXX10"
),
AEBODSYS = c(
"SOC 1", "SOC 2", "SOC 1", "SOC 2", "SOC 2",
"SOC 2", "SOC 2", "SOC 1", "SOC 2", "SOC 1"
),
AEDECOD = c(
"Coded Term 2", "Coded Term 1", "Coded Term 3", "Coded Term 4",
"Coded Term 4", "Coded Term 4", "Coded Term 5", "Coded Term 3",
"Coded Term 1", "Coded Term 2"
),
TRT01A = c(
"ARMA", "ARMB", "ARMA", "ARMB", "ARMB",
"Placebo", "Placebo", "Placebo", "ARMA", "ARMB"
),
TRTEMFL = c("Y", "Y", "N", "Y", "Y", "Y", "Y", "N", "Y", "Y")
)
ADAE <- ADAE |>
dplyr::mutate(TRT01A = as.factor(TRT01A))
ADAE$colspan_trt <- factor(ifelse(ADAE$TRT01A == "Placebo", " ", "Active Study Agent"),
levels = c("Active Study Agent", " ")
)
ADAE$rrisk_header <- "Risk Difference (%) (95% CI)"
ADAE$rrisk_label <- paste(ADAE$TRT01A, paste("vs", "Placebo"))
colspan_trt_map <- create_colspan_map(ADAE,
non_active_grp = "Placebo",
non_active_grp_span_lbl = " ",
active_grp_span_lbl = "Active Study Agent",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
ref_path <- c("colspan_trt", " ", "TRT01A", "Placebo")
ADSL <- unique(ADAE |> select(USUBJID, "colspan_trt", "rrisk_header", "rrisk_label", "TRT01A"))
lyt <- basic_table() |>
split_cols_by(
"colspan_trt",
split_fun = trim_levels_to_map(map = colspan_trt_map)
) |>
split_cols_by("TRT01A") |>
split_cols_by("rrisk_header", nested = FALSE) |>
split_cols_by(
"TRT01A",
labels_var = "rrisk_label",
split_fun = remove_split_levels("Placebo")
) |>
analyze(
"TRTEMFL",
a_freq_j,
show_labels = "hidden",
extra_args = list(
method = "wald",
label = "Subjects with >=1 AE",
ref_path = ref_path,
.stats = "count_unique_fraction"
)
) |>
split_rows_by("AEBODSYS",
split_label = "System Organ Class",
split_fun = trim_levels_in_group("AEDECOD"),
label_pos = "topleft",
section_div = c(" "),
nested = FALSE
) |>
summarize_row_groups(
"AEBODSYS",
cfun = a_freq_j,
extra_args = list(
method = "wald",
ref_path = ref_path,
.stats = "count_unique_fraction"
)
) |>
analyze(
"AEDECOD",
afun = a_freq_j,
extra_args = list(
method = "wald",
ref_path = ref_path,
.stats = "count_unique_fraction"
)
)
result <- build_table(lyt, ADAE, alt_counts_df = ADSL)
result
result <- sort_at_path(
result,
c("root", "AEBODSYS"),
scorefun = jj_complex_scorefun()
)
result <- sort_at_path(
result,
c("root", "AEBODSYS", "*", "AEDECOD"),
scorefun = jj_complex_scorefun()
)
result
Numeric Formatting Function
Description
Formatting setter for selected numerical statistics.
Usage
jjcs_num_formats(d, cap = 4)
Arguments
d |
( |
cap |
( |
Value
list:
fmt : named vector with formatting function (jjcsformat_xx) for numerical stats: range, median, mean_sd, sd
spec : named vector with formatting specifications for numerical stats: range, median, mean_sd, sd
Examples
P1_precision <- jjcs_num_formats(d = 0)$fmt
jjcs_num_formats(2)$fmt
jjcs_num_formats(2)$spec
Formatting function for percentage values
Description
Formats fractional values as percentages with special consideration for values that round to 0 or 100, as well as missing values. The input is expected to be a fraction, which is multiplied by 100 internally before formatting. Missing values are formatted as "-".
Usage
jjcsformat_fraction(
x,
round_type = valid_round_type,
output = c("ascii", "html"),
d = 1,
add_pct = FALSE,
verbose = FALSE,
...
)
Arguments
x |
( |
round_type |
( |
output |
( |
d |
( |
add_pct |
( |
verbose |
( |
... |
Additional arguments passed to other methods. |
Value
A formatted string.
Author(s)
WW
See Also
Other JJCS formatting functions:
count and fraction related formatting functions,
jjcsformat_xx()
Examples
jjcsformat_fraction(0.15)
jjcsformat_fraction(0.15, d = 2)
jjcsformat_fraction(0.15, d = 2, verbose = TRUE)
Utility for specifying custom formats
Description
Utility for specifying custom formats that can be used as a format in formatters::format_value
A function factory to generate formatting functions for p-value formatting that support rounding close to the significance level specified.
A function factory to generate formatting functions for range formatting that includes information about the censoring of survival times.
Usage
jjcsformat_xx(
str,
na_str = na_str_dflt,
na_str_dflt = "NE",
replace_na_dflt = TRUE
)
jjcsformat_pval_fct(alpha = 0.05)
jjcsformat_range_fct(str, censor_char = "+")
Arguments
str |
( |
na_str |
String for NA values. |
na_str_dflt |
Character to represent NA value |
replace_na_dflt |
logical(1). Should an |
alpha |
( |
censor_char |
( |
Value
Either a supported format string, or a formatting function that can be
used as format in formatters::format_value
The p-value in the standard format. If count is 0, the format is 0.
If it is smaller than 0.001, then <0.001, if it is larger than 0.999, then
>0.999 is returned. Otherwise, 3 digits are used. In the special case that
rounding from below would make the string equal to the specified alpha,
then a higher number of digits is used to be able to still see the difference.
For example, 0.0048 is not rounded to 0.005 but stays at 0.0048 if alpha = 0.005
is set.
A function that formats a numeric vector with 4 elements:
minimum
maximum
censored minimum? (1 if censored, 0 if event)
censored maximum? (1 if censored, 0 if event) The range along with the censoring information is returned as a string with the specified numeric format as
(min, max), and thecensor_charis appended tominormaxif these have been censored.
See Also
Other JJCS formatting functions:
count and fraction related formatting functions,
jjcsformat_fraction()
Examples
value <- c(1.65, 8.645)
fmt <- jjcsformat_xx("xx.x")
is.function(fmt)
fmt
format_value(value[1], fmt, round_type = "sas")
format_value(value[1], fmt, round_type = "iec")
if (is.function(fmt)) fmt(value[1])
fmt2 <- jjcsformat_xx("xx.x (xx.xxx)")
is.function(fmt2)
value <- c(1.65, 8.645)
format_value(value, fmt2, round_type = "sas")
format_value(value, fmt2, round_type = "iec")
# only possible when resulting format is a function
if (is.function(fmt2)) fmt2(value, round_type = "sas")
value <- c(1.65, NA)
format_value(value, fmt2, round_type = "iec", na_str = c("ne1", "ne2"))
if (is.function(fmt2)) fmt2(value, round_type = "iec", na_str = c("ne1", "ne2"))
my_pval_format <- jjcsformat_pval_fct(0.005)
my_pval_format(0.2802359)
my_pval_format(0.0048)
my_pval_format(0.00499)
my_pval_format(0.004999999)
my_pval_format(0.0051)
my_pval_format(0.0009)
my_pval_format(0.9991)
my_range_format <- jjcsformat_range_fct("xx.xx")
my_range_format(c(0.35235, 99.2342, 1, 0))
my_range_format(c(0.35235, 99.2342, 0, 1))
my_range_format(c(0.35235, 99.2342, 0, 0))
my_range_format(c(0.35235, 99.2342, 1, 1))
my_range_format <- jjcsformat_range_fct("xx.xx", censor_char = "*")
my_range_format(c(0.35235, 99.2342, 1, 1))
Pruning Function to accommodate removal of completely NULL rows within a table
Description
Condition function on individual analysis rows. Flag as FALSE when all columns are NULL, as then the row should not be kept. To be utilized as a row_condition in function tern::keep_rows
Usage
keep_non_null_rows(tr)
Arguments
tr |
( |
Value
A function that can be utilized as a row_condition in the tern::keep_rows function.
Examples
library(dplyr)
ADSL <- data.frame(
USUBJID = c(
"XXXXX01", "XXXXX02", "XXXXX03", "XXXXX04", "XXXXX05",
"XXXXX06", "XXXXX07", "XXXXX08", "XXXXX09", "XXXXX10"
),
TRT01P = c(
"ARMA", "ARMB", "ARMA", "ARMB", "ARMB", "Placebo",
"Placebo", "Placebo", "ARMA", "ARMB"
),
AGE = c(34, 56, 75, 81, 45, 75, 48, 19, 32, 31),
SAFFL = c("N", "N", "N", "N", "N", "N", "N", "N", "N", "N"),
PKFL = c("N", "N", "N", "N", "N", "N", "N", "N", "N", "N")
)
ADSL <- ADSL |>
mutate(TRT01P = as.factor(TRT01P))
create_blank_line <- function(x) {
list(
"Mean" = rcell(mean(x), format = "xx.x"),
" " = rcell(NULL),
"Max" = rcell(max(x))
)
}
lyt <- basic_table() |>
split_cols_by("TRT01P") |>
analyze("AGE", afun = create_blank_line)
result <- build_table(lyt, ADSL)
result
result <- prune_table(result, prune_func = tern::keep_rows(keep_non_null_rows))
result
Adding Labels To Variables For Model
Description
Adding Labels To Variables For Model
Usage
h_is_specified(x, vars)
h_is_specified_and_in_data(x, vars, data)
h_check_and_get_label(x, vars, data)
h_labels(vars, data)
Arguments
x |
( |
vars |
( |
data |
( |
Functions
-
h_is_specified(): checks if element invarsis notNULLand not empty. -
h_is_specified_and_in_data(): checks if element in vars is not NULL and exists in dataset. -
h_check_and_get_label(): gets label for each element in vars. -
h_labels(): returns the list of variables with labels.
Extract the left-hand side of a formula
Description
Extract the left-hand side of a formula
Usage
leftside(x)
Arguments
x |
( |
Value
(character(1)) The name of the left-hand side of the formula.
Examples
leftside(y ~ x)
Define Column Widths
Description
def_colwidths uses heuristics to determine suitable column widths given a
table or listing, and a font.
Usage
listing_column_widths(
mpf,
incl_header = TRUE,
col_gap = 0.5,
pg_width_ins = 8.88,
fontspec = font_spec("Times", 8, 1.2),
verbose = FALSE
)
def_colwidths(
tt,
fontspec,
label_width_ins = 2,
col_gap = ifelse(type == "Listing", 0.5, 3),
type = tlg_type(tt)
)
Arguments
mpf |
( |
incl_header |
( |
col_gap |
Column gap in spaces. Defaults to |
pg_width_ins |
( |
fontspec |
Font specification |
verbose |
( |
tt |
input TableTree |
label_width_ins |
Label Width in Inches. |
type |
Type of the TableTree, used to determine column width calculation method. |
Details
Listings are assumed to be rendered landscape on standard A1 paper,
such that all columns are rendered on one page. Tables are allowed to
be horizontally paginated, and column widths are determined based only on
required word wrapping. See the Automatic Column Widths vignette for
a detailed discussion of the algorithms used.
Value
-
listing_column_widths: a vector of column widths suitable to use intt_to_tlgrtfand other exporters.
-
def_colwidths: a vector of column widths (including the label row pseudo-column in the table case) suitable for use renderingttin the specified font.
Helpers for Processing Least Square Means
Description
Helpers for Processing Least Square Means
Usage
h_partial_match(options, x)
h_get_emmeans_res(fit, vars, weights)
h_get_average_visit_specs(emmeans_res, vars, averages, fit)
h_get_spec_visit_estimates(emmeans_res, specs, conf_level, tests = FALSE, ...)
h_get_single_visit_estimates(emmeans_res, conf_level)
h_get_relative_reduc_df(estimates, vars)
h_single_visit_contrast_specs(emmeans_res, vars)
h_average_visit_contrast_specs(specs, averages, vars)
h_get_mult_adj_estimates(emmeans_res, vars, mult_adj, conf_level, contrast_df)
Arguments
options |
( |
x |
( |
fit |
result of model fitting function, e.g. |
vars |
(named
Note that the main effects and interaction of |
weights |
( |
emmeans_res |
( |
averages |
( |
specs |
( |
conf_level |
( |
tests |
( |
... |
additional arguments for |
estimates |
( |
contrast_df |
( |
Functions
-
h_partial_match(): partial matching of a set ofoptionsto a character vectorx. Here partial matching means that for each element ofxwe look for the (first) element ofoptionswhich is contained in the element ofx. Then we return the matchedoptionsin the same order asx. -
h_get_emmeans_res(): returns a list withobject(emmGridobject containingemmeansresults) andgrid(data.framecontaining the (optional) subgroup, arm and the visit variables together with the sample sizenfor each combination). -
h_get_average_visit_specs(): constructs average of visits specifications. -
h_get_spec_visit_estimates(): estimates least square means as adata.framegiven specifications. -
h_get_single_visit_estimates(): estimates least square means for single visits. -
h_get_relative_reduc_df(): constructsdata.framewith relative reduction vs. reference arm based on single visit estimates. -
h_single_visit_contrast_specs(): constructs single visit contrast specifications. -
h_average_visit_contrast_specs(): constructs average visits contrast specifications, given thespecsfor single visit contrasts and the averages required. -
h_get_mult_adj_estimates(): Computes multiplicity-adjusted p-values and confidence intervals for treatment-vs-reference contrasts usingmultcomp. Returns adata.framewith the arm and visit grid columns plusp_value,p_value_less,p_value_greater,lower_cl, andupper_cl.
Note
The difference here compared to the original tern.mmrm::h_get_spec_visit_estimates()
function is that additional arguments for emmeans::contrast() can be passed via the
dots (...) argument.
Once this has been added to the tern.mmrm package then its functions can be used instead.
Layout Generating Function for LS Means Wide Table Layouts
Description
Layout Generating Function for LS Means Wide Table Layouts
Usage
lsmeans_wide_first_split_fun_fct(include_variance)
lsmeans_wide_second_split_fun_fct(pval_sided, conf_level, include_pval)
lsmeans_wide_cfun(
df,
labelstr,
.spl_context,
variables,
ref_level,
treatment_levels,
pval_sided = c("2", "1", "-1"),
conf_level,
formats
)
summarize_lsmeans_wide(
lyt,
variables,
ref_level,
treatment_levels,
conf_level,
pval_sided = "2",
include_variance = TRUE,
include_pval = TRUE,
formats = list(lsmean = jjcsformat_xx("xx.x"), mse = jjcsformat_xx("xx.x"), df =
jjcsformat_xx("xx."), lsmean_diff = jjcsformat_xx("xx.x"), se =
jjcsformat_xx("xx.xx"), ci = jjcsformat_xx("(xx.xx, xx.xx)"), pval =
jjcsformat_pval_fct(0))
)
Arguments
include_variance |
( |
pval_sided |
( |
conf_level |
( |
include_pval |
( |
df |
( |
labelstr |
( |
.spl_context |
( |
variables |
( |
ref_level |
( |
treatment_levels |
( |
formats |
( |
lyt |
( |
Details
The functions lsmeans_wide_first_split_fun_fct(), lsmeans_wide_second_split_fun_fct() and
lsmeans_wide_cfun() are also exported and can be used directly when the layout is slightly different (e.g.
contains additional subgroup row split).
Value
Modified layout.
Examples
variables <- list(
response = "FEV1",
covariates = c("RACE", "SEX"),
arm = "ARMCD",
id = "USUBJID",
visit = "AVISIT"
)
fit <- fit_ancova(
vars = variables,
data = mmrm::fev_data,
conf_level = 0.9,
weights_emmeans = "equal"
)
anl <- broom::tidy(fit)
basic_table() |>
summarize_lsmeans_wide(
variables = variables,
ref_level = fit$ref_level,
treatment_levels = fit$treatment_levels,
pval_sided = "2",
conf_level = 0.8
) |>
build_table(df = anl)
Split Function Helper
Description
A function which aids the construction for users to create their own split function for combined columns.
Usage
make_combo_splitfun(nm, label = nm, levels = NULL, rm_other_facets = TRUE)
Arguments
nm |
( |
label |
( |
levels |
( |
rm_other_facets |
( |
Value
Function usable directly as a split function.
Examples
aesevall_spf <- make_combo_splitfun(nm = "AESEV_ALL", label = "Any AE", levels = NULL)
Make Multi-comparator Split Function
Description
Create a custom splitting function suitable for creating risk
difference columns against one or more comparators. This is used
within col_struct_w_risk_diffs.
Usage
make_multicomp_splfun(
colspan_trt_map,
combo_levels_map = NULL,
comp_level_map = NULL,
.pre = list(),
.post = list()
)
make_dflt_comp_map(df, spl_var, ref_lvls, combo_map)
Arguments
colspan_trt_map |
( |
combo_levels_map |
( |
comp_level_map |
( |
.pre |
|
.post |
|
df |
( |
spl_var |
( |
ref_lvls |
( |
combo_map |
( |
Details
This split function is intended to create a set of risk difference
or similar columns. As such it will automatically exclude the facet
for each comparator level (e.g., Placebo vs Placebo) as determined
by the last element of each element of comp_level_paths.
Further control of facets is provided by comp_level_map. If
NULL (the default), all non-control/reference groups will be
compared pairwise with all control/reference groups as defined by
the grouping in colspan_trt_map.
If specified, comp_level_map must be a data.frame (including
tbl_df) with three columns:
-
active- (character) the value to be compared to a reference level, -
comparator- (character) the level that should be compared against, and -
active_is_combo- (logical) is the level specified inactivea virtual combination level. -
comparator_is_combo- (logical) is the level specified incomparatora virtual combination level.
If a data.frame with only the active and comparator columns
is given for comp_level_map, active_is_combo and
comparator_is_combo are inferred from colspan_trt_map.
If any rows of comp_level_map have active_is_combo == TRUE or
comparator_is_combo, the relevant values in those rows must
also appear in combo_levels_map with the correct level for
comp_level (or the select_all_levels sentinel value which
indicates inclusion for all comparators).
If specified, combo_levels_map must be a data.frame (including tbl_df)
with the following columns:
-
valname- (character) The name(s) for the combination level(s), -
label- (character) the label(s) for the combination level(s), -
levelcombo- (listofcharacter) the levels of the split variable to be combined, orselect_all_levelsfor all levels, -
exargs- (list) the extra_args values for each combo level. If not present this will be assumed to belist()for all combo levels. -
compare_against- (listofcharacter) Optional. The reference level(s) the combo level should be compared against, orselect_all_levelsfor inclusion against all comparators. -
is_control- (logical) Optional. Is this combination level going to be used as a reference level (must appear as the last element in one ofcomp_level_pathsif so).
When specifying combo_levels_map if the compare_against column
is omitted, comparison against all reference levels will be
performed for all combination levels. If is_control is omitted,
it will be assumed as FALSE for all combination levels.
Order of combination levels when multiple are present for a single
comparator, as well as their position relative to non-combination
comparisons, is determined by row order in combo_levels_map.
Labels and names of comparison columns involving combination levels
will be automatically computed in the form of
"<combo level name/label> vs <ref group name>". Note currently
ref group name is always used as it needs to be inferable from
colspan_trt_map.
The comparator reference path is calculated based on
colspan_trt_map and then added as ref_path to the extra_args
associated with generated facet. As such, analysis (or content)
functions used underneath a split using the generated split
function must accept either ref_path or ....
Value
A split function suitable for use in both split_rows_by
and split_cols_by.
For make_dflt_comp_map(), a data.frame with columns
active, comparator, active_is_combo, and comparator_is_combo,
listing the comparisons to keep and whether either side is a virtual
combination level.
Note
It is not currently possible to use a virtual combination level as a comparator/reference group. If you need this functionality please contact the maintainers by filing an issue at https://github.com/johnsonandjohnson/junco/issues
See Also
Other std_col_struct:
grouped_cols_w_diffs(),
shift_tbl_col_struct()
Create a rbmi ready cluster
Description
Use
rbmi::make_rbmi_cluster() instead.
Usage
make_rbmi_cluster(cluster_or_cores = 1, objects = NULL, packages = NULL)
Arguments
cluster_or_cores |
( |
objects |
( |
packages |
( |
Value
See rbmi::make_rbmi_cluster().
No Data to Report String
Description
A constant string used when there is no data to display in a table. This is used as a placeholder in tables when no data is available for a particular category.
Usage
no_data_to_report_str
Value
A character string with the value "No data to report".
Odds ratio estimation
Description
A set of functions for Odds-Ratio (OR) calculation.
Usage
a_odds_ratio_j(
df,
.var,
.df_row,
ref_path,
.spl_context,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
s_odds_ratio_j(
df,
.var,
.ref_group,
.in_ref_col,
.df_row,
variables = list(arm = NULL, strata = NULL),
conf_level = 0.95,
groups_list = NULL,
na_if_no_events = TRUE,
method = c("exact", "approximate", "efron", "breslow", "cmh")
)
Arguments
df |
( |
.var |
( |
.df_row |
( |
ref_path |
( |
.spl_context |
( |
... |
Additional arguments passed to the statistics function. |
.stats |
( |
.formats |
( |
.labels |
( |
.indent_mods |
( |
.ref_group |
( |
.in_ref_col |
( |
variables |
( |
conf_level |
( |
groups_list |
( |
na_if_no_events |
( |
method |
( |
Value
-
a_odds_ratio_j()returns the corresponding list with formattedrtables::CellValue().
-
s_odds_ratio_j()returns a named list with the statisticsor_ci(containingest,lcl, anducl),pvalandn_tot.
Functions
-
a_odds_ratio_j(): Formatted analysis function which is used asafun. Note that the junco specificref_pathand.spl_contextarguments are used for reference column information. -
s_odds_ratio_j(): Statistics function which estimates the odds ratio between a treatment and a control. Avariableslist witharmandstratavariable names must be passed if a stratified analysis is required.
Note
The a_odds_ratio_j() and s_odds_ratio_j() functions have the _j suffix to distinguish them
from tern::a_odds_ratio() and tern::s_odds_ratio(), respectively.
These functions differ as follows:
Additional
method = 'cmh'option is provided to calculate the Cochran-Mantel-Haenszel estimate.The p-value is returned as an additional statistic.
Once these updates are contributed back to tern, they can later be replaced by the tern versions.
Examples
set.seed(12)
dta <- data.frame(
rsp = sample(c(TRUE, FALSE), 100, TRUE),
grp = factor(rep(c("A", "B"), each = 50), levels = c("A", "B")),
strata = factor(sample(c("C", "D"), 100, TRUE))
)
a_odds_ratio_j(
df = subset(dta, grp == "A"),
.var = "rsp",
ref_path = c("grp", "B"),
.spl_context = data.frame(
cur_col_split = I(list("grp")),
cur_col_split_val = I(list(c(grp = "A"))),
full_parent_df = I(list(dta))
),
.df_row = dta
)
l <- basic_table() |>
split_cols_by(var = "grp") |>
analyze(
"rsp",
afun = a_odds_ratio_j,
show_labels = "hidden",
extra_args = list(
ref_path = c("grp", "B"),
.stats = c("or_ci", "pval")
)
)
build_table(l, df = dta)
l2 <- basic_table() |>
split_cols_by(var = "grp") |>
analyze(
"rsp",
afun = a_odds_ratio_j,
show_labels = "hidden",
extra_args = list(
variables = list(arm = "grp", strata = "strata"),
method = "cmh",
ref_path = c("grp", "A"),
.stats = c("or_ci", "pval")
)
)
build_table(l2, df = dta)
s_odds_ratio_j(
df = subset(dta, grp == "A"),
.var = "rsp",
.ref_group = subset(dta, grp == "B"),
.in_ref_col = FALSE,
.df_row = dta
)
s_odds_ratio_j(
df = subset(dta, grp == "A"),
.var = "rsp",
.ref_group = subset(dta, grp == "B"),
.in_ref_col = FALSE,
.df_row = dta,
variables = list(arm = "grp", strata = "strata")
)
s_odds_ratio_j(
df = subset(dta, grp == "A"),
method = "cmh",
.var = "rsp",
.ref_group = subset(dta, grp == "B"),
.in_ref_col = FALSE,
.df_row = dta,
variables = list(arm = "grp", strata = c("strata"))
)
Function Factory to Create Padded In Rows Content
Description
Function Factory to Create Padded In Rows Content
Usage
pad_in_rows_fct(length_out = NULL, label = "")
Arguments
length_out |
( |
label |
( |
Value
The function of content and .formats.
Parallelise Lapply
Description
This internal helper is no longer exported.
Use
rbmi::analyse() directly.
Usage
par_lapply(cl, fun, x, ...)
Arguments
cl |
( |
fun |
( |
x |
( |
... |
Extra arguments passed to |
Value
list of results of calling fun on elements of x.
Pool a scalar estimate across imputations
Description
Applies Rubin's rules to combine scalar estimates and their within-imputation variance estimates.
Usage
pool_rubin_scalar(q, u)
Arguments
q |
( |
u |
( |
Details
For m imputations, the pooled estimate is the mean of q. The
pooled variance combines the mean within-imputation variance with the
between-imputation variance, using the usual (1 + 1 / m) multiplier.
The returned standard error is the square root of the pooled variance.
Value
A named list with the pooled estimate (est), standard error
(se), variance (var), and number of imputations (m).
See Also
Examples
pool_rubin_scalar(
q = c(0.20, 0.25, 0.15),
u = c(0.01, 0.016, 0.012)
)
Pool z statistics across imputations
Description
Combines z statistics from multiple imputed datasets and calculates a two-sided p-value for the pooled statistic.
Usage
pool_z_stat(z_stat_vals)
Arguments
z_stat_vals |
( |
Details
The within-imputation variance of a z statistic is approximately 1.
The between-imputation variance is pooled using the same
(1 + 1 / m) multiplier as pool_rubin_scalar(). The returned p-value is
calculated from the standard normal distribution.
Value
A named list with the pooled z statistic (z) and its two-sided
p-value (p).
See Also
Examples
pool_z_stat(c(1.1, 1.3, 1.2))
Prepend a Label Row to a RowsVerticalSection Object
Description
Prepends a label row to a RowsVerticalSection object.
RowsVerticalSection objects are returned by analysis functions used within
the rtables framework and are typically created with
rtables::in_rows().
This function is typically used to introduce section headers (e.g., "Descriptive Statistics") in tabular reports and other reporting outputs.
Usage
prepend_label_cell(x, label = "", label_indent_mod = 0L)
Arguments
x |
( |
label |
( |
label_indent_mod |
( |
Value
A RowsVerticalSection object with a label row prepended.
Note
The row_na_strs and row_footnotes attributes of the
RowsVerticalSection object are not preserved.
Since an additional row is added, be aware of recycling rules; that is,
the length of all attributes of x should be equal to length(x).
Examples
rvs <- rtables::in_rows(
Mean = rtables::rcell(5),
Range = rtables::rcell(c(1, 8))
)
prepend_label_cell(
rvs,
"Descriptive Statistics",
label_indent_mod = 1L
)
Proportion difference estimation
Description
The analysis function a_proportion_diff_j() can be used to create a layout element to estimate
the difference in proportion of responders within a studied population. The primary analysis variable,
vars, is a logical variable indicating whether a response has occurred for each record. See the method
parameter for options of methods to use when constructing the confidence interval of the proportion difference.
A stratification variable can be supplied via the strata element of the variables argument.
Usage
a_proportion_diff_j(
df,
.var,
ref_path,
.spl_context,
...,
conf_level = 0.95,
label = paste0("% Difference (", f_conf_level(conf_level), ")"),
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
Arguments
df |
( |
.var |
( |
ref_path |
( |
.spl_context |
( |
... |
Additional arguments passed to the statistics function. |
conf_level |
( |
label |
( |
.stats |
( |
.formats |
( |
.labels |
( |
.indent_mods |
( |
Value
-
a_proportion_diff_j()returns the corresponding list with formattedrtables::CellValue().
Functions
-
a_proportion_diff_j(): Formatted analysis function which is used asafuninestimate_proportion_diff().
Note
The a_proportion_diff_j() function has the _j suffix to distinguish it
from tern::a_proportion_diff(). It is a thin wrapper around
tern::s_proportion_diff() with the following additions:
The
diff_est_cistatistic (returned natively by tern since tern#1523) is relabelled with a shorter junco-style label ("% Difference (conf_level CI)").-
ref_pathneeds to be provided as extra argument to specify the control group column.
Examples
nex <- 100
dta <- data.frame(
"rsp" = sample(c(TRUE, FALSE), nex, TRUE),
"grp" = sample(c("A", "B"), nex, TRUE),
"f1" = sample(c("a1", "a2"), nex, TRUE),
"f2" = sample(c("x", "y", "z"), nex, TRUE),
stringsAsFactors = TRUE
)
l <- basic_table() |>
split_cols_by(var = "grp") |>
analyze(
vars = "rsp",
afun = a_proportion_diff_j,
show_labels = "hidden",
na_str = tern::default_na_str(),
extra_args = list(
conf_level = 0.9,
method = "ha",
ref_path = c("grp", "B")
)
)
build_table(l, df = dta)
Difference test for two proportions
Description
The analysis function a_test_proportion_diff() can be used to create a layout element to test
the difference between two proportions. The primary analysis variable, vars, indicates whether a
response has occurred for each record. See the method parameter for options of methods to use
to calculate the p-value. Additionally, a stratification variable can be supplied via the strata
element of the variables argument. The argument alternative specifies the direction of the
alternative hypothesis.
Usage
a_test_proportion_diff(
df,
.var,
ref_path,
.spl_context,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
Arguments
df |
( |
.var |
( |
ref_path |
( |
.spl_context |
( |
... |
Additional arguments passed to
|
.stats |
( |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
Value
-
a_test_proportion_diff()returns the corresponding list with formattedrtables::CellValue().
Functions
-
a_test_proportion_diff(): Formatted analysis function which is used asafun
Note
This function has been forked from the tern package. Additional features are:
Additional
ref_pathargument for flexible reference column path specification.
Examples
dta <- data.frame(
rsp = sample(c(TRUE, FALSE), 100, TRUE),
grp = factor(rep(c("A", "B"), each = 50)),
strata = factor(rep(c("V", "W", "X", "Y", "Z"), each = 20))
)
l <- basic_table() |>
split_cols_by(var = "grp") |>
analyze(
vars = "rsp",
afun = a_test_proportion_diff,
show_labels = "hidden",
extra_args = list(
method = "cmh",
variables = list(strata = "strata"),
ref_path = c("grp", "B")
)
)
build_table(l, df = dta)
Split Function for Proportion Analysis Columns
Description
Here we just split into 3 columns n, % and Cum %.
Usage
prop_post_fun(ret, spl, fulldf, .spl_context)
prop_split_fun(df, spl, vals = NULL, labels = NULL, trim = FALSE, .spl_context)
Arguments
ret |
( |
spl |
( |
fulldf |
( |
.spl_context |
( |
df |
A data frame that contains all analysis variables. |
vals |
A character vector that contains values to use for the split. |
labels |
A character vector that contains labels for the statistics (without indent). |
trim |
A single logical that indicates whether to trim the values. |
Value
a split function for use in rtables::split_rows_by.
See Also
rtables::make_split_fun() describing the requirements for this kind of
post-processing function.
Relative Risk CMH Statistic
Description
Calculates the relative risk which is defined as the ratio between the response rates between the experimental treatment group and the control treatment group, adjusted for stratification factors by applying Cochran-Mantel-Haenszel (CMH) weights.
Usage
prop_ratio_cmh(rsp, grp, strata, conf_level = 0.95)
Arguments
rsp |
( |
grp |
( |
strata |
( |
conf_level |
( |
Value
A list with elements rel_risk_ci and pval.
Examples
set.seed(2)
rsp <- sample(c(TRUE, FALSE), 100, TRUE)
grp <- sample(c("Placebo", "Treatment"), 100, TRUE)
grp <- factor(grp, levels = c("Placebo", "Treatment"))
strata_data <- data.frame(
"f1" = sample(c("a", "b"), 100, TRUE),
"f2" = sample(c("x", "y", "z"), 100, TRUE),
stringsAsFactors = TRUE
)
prop_ratio_cmh(
rsp = rsp, grp = grp, strata = interaction(strata_data),
conf_level = 0.90
)
Formatted Analysis Function for Proportion Analysis
Description
This function applies to a factor x when a column split was prepared with
prop_split_fun() before.
Usage
prop_table_afun(x, .spl_context, formats, add_total_level = FALSE)
Arguments
x |
( |
.spl_context |
( |
formats |
( |
add_total_level |
( |
Details
In the column named n, the counts of the categories as well as an
optional Total count will be shown. In the column named percent, the
percentages of the categories will be shown, with an optional blank entry for
Total. In the column named cum_percent, the cumulative percentages will
be shown instead.
Value
A VerticalRowsSection as returned by rtables::in_rows.
Proportion Difference with Method Selection Based on the Mantel-Fleiss Criterion
Description
Performs an adaptive analysis of the difference in response proportions between a non-reference group and a reference group for stratified data, with the method selected based on the Mantel-Fleiss (MF) criterion.
When the Mantel-Fleiss criterion is satisfied, a Cochran-Mantel-Haenszel
(CMH) analysis is performed using the method specified by mf_method.
When the criterion is not satisfied, an unconditional exact method is used
instead.
Usage
a_proportion_diff_mf(
df,
.var,
.in_ref_col = NULL,
.ref_group = NULL,
val = TRUE,
variables = list(strata = NULL),
na.rm = FALSE,
conf_level = 0.95,
mf_method = c("cmh", "cmh_sato", "cmh_mn"),
mf_threshold = NULL,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL,
exact_footnote = rtables::RefFootnote(note = tern::d_proportion_diff(method =
"uncond_exact_diff", method_only = TRUE), index = 1L, symbol = "+")
)
s_proportion_diff_mf(
df,
.var,
.in_ref_col = NULL,
.ref_group = NULL,
val = TRUE,
variables = list(strata = NULL),
na.rm = FALSE,
conf_level = 0.95,
mf_method = c("cmh", "cmh_sato", "cmh_mn"),
mf_threshold = NULL
)
Arguments
df |
( |
.var |
( |
.in_ref_col |
( |
.ref_group |
( |
val |
( |
variables |
( |
na.rm |
( This argument is passed unchanged to the |
conf_level |
( |
mf_method |
( |
mf_threshold |
( |
... |
additional arguments for the lower level functions. |
.stats |
( |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
exact_footnote |
( |
Details
The data are prepared by tern::h_prepare_rsp_table(), which constructs the
response vector, group indicator, optional strata variable, and the
corresponding 2 x 2 contingency table(s). When multiple strata variables are
supplied, the cross-combinations of their levels define the analysis strata.
The response variable is converted to a binary response according to val.
The analysis compares the response proportion in the non-reference group with
that in the reference group. The difference is calculated as the
non-reference group minus the reference group.
When strata are provided and the Mantel-Fleiss criterion is satisfied, the
selected CMH method tern::prop_diff_cmh() is used to obtain the point
estimate and confidence interval for the difference in response proportions.
The available Cochran-Mantel-Haenszel-type methods for estimating the
difference in response proportions and its confidence interval are:
-
"cmh": CMH method. -
"cmh_sato": CMH method using the Sato variance estimator. -
"cmh_mn": CMH method using the Miettinen-Nurminen method.
See tern::prop_diff_cmh() for more details and references.
When strata are not specified, or when strata are specified but the
Mantel-Fleiss criterion is not satisfied or cannot be evaluated (e.g., when
all strata contain no observed values), the unconditional exact method
tern::prop_diff_uncond_exact() is used to obtain the point estimate and
confidence interval.
The Mantel-Fleiss criterion is evaluated using tern::mantel_fleiss_crit().
The statistics function s_proportion_diff_mf() follows the usage and output
of tern::s_proportion_diff() but removes the method argument and selects
internally between a Cochran-Mantel-Haenszel-type method and an unconditional
exact method based on the Mantel-Fleiss criterion.
Value
-
a_proportion_diff_mf()returns the correspondingRowsVerticalSectionobject with formatted results.
-
s_proportion_diff_mf()returns a list containing:diff(numeric(1)ornumeric(0))Point estimate of the difference in response proportions, or
numeric(0)when the function is evaluated for the reference column (.in_ref_colis NULL or.in_ref_colisTRUE).diff_ci(numeric(2)ornumeric(0))Confidence interval for the difference in response proportions, or
numeric(0)when the function is evaluated for the reference column (.in_ref_colis NULL or.in_ref_colisTRUE).diff_est_ci(numeric(3)ornumeric(0))Point estimate and confidence interval for the difference in response proportions, or
numeric(0)when the function is evaluated for the reference column (.in_ref_colis NULL or.in_ref_colisTRUE).executed_method(character(1))Name of the method actually used for the analysis. Takes the value
NA_character_when the function is evaluated for the reference column (.in_ref_colisNULLor.in_ref_colisTRUE). Otherwise, identifies the method used:"cmh","cmh_sato","cmh_mn", or"uncond_exact_diff". Formatted analysis functions can use this value to determine whether an appropriate footnote should be added.
Functions
-
a_proportion_diff_mf(): Formatted analysis function used asafunfor the difference in response proportions with method selection based on the Mantel-Fleiss criterion. -
s_proportion_diff_mf(): Statistics function estimating the difference in response proportions and its confidence interval. When strata variables are provided and the Mantel-Fleiss criterion is satisfied, the CMH methodtern::prop_diff_cmh()is used, with thediff_seargument determined bymf_method. Otherwise, i.e., when strata variables are not provided, or when strata variables are provided but the Mantel-Fleiss criterion is not satisfied or cannot be evaluated, the unconditional exact methodtern::prop_diff_uncond_exact()is used.
Author(s)
WW
See Also
Examples
n <- 100 # Number of observations.
set.seed(123)
dta <- data.frame(
"rsp" = sample(c("Y", "N"), n, TRUE),
"grp" = c(
sample(c("A", "Placebo"), round(n - 0.1 * n), TRUE),
rep("C", round(0.1 * n))
),
"f1" = sample(c("a1", "a2"), n, TRUE),
"f2" = sample(c("x", "y", "z"), n, TRUE),
stringsAsFactors = TRUE
)
lyt <- basic_table() |>
split_cols_by(var = "grp", ref_group = "Placebo") |>
analyze(
vars = "rsp",
afun = a_proportion_diff_mf,
extra_args = list(
val = "Y",
variables = list(strata = c("f1", "f2")),
conf_level = 0.90,
mf_method = "cmh_mn",
.stats = "diff_est_ci"
)
)
build_table(lyt, df = dta)
prop_d <- s_proportion_diff_mf(
df = subset(dta, grp == "A"),
.var = "rsp",
.ref_group = subset(dta, grp == "Placebo"),
.in_ref_col = FALSE,
val = "Y",
variables = list(strata = c("f1", "f2")),
conf_level = 0.90,
mf_method = "cmh_mn"
)
prop_d
Standard Arguments
Description
The documentation to this function lists all the arguments in tern
that are used repeatedly to express an analysis.
Arguments
... |
additional arguments for the lower level functions. |
.aligns |
( |
.all_col_counts |
( |
.df_row |
( |
.formats |
(named |
.in_ref_col |
( |
.indent_mods |
(named |
.labels |
(named |
.N_col |
( |
.N_row |
( |
.ref_group |
( |
ref_path |
( |
.spl_context |
( |
.stats |
( |
.var |
( |
add_total_level |
( |
alternative |
( |
col_by |
( |
conf_level |
( |
control |
( |
data |
( |
df |
( |
draw |
( |
exclude_levels |
( |
grp |
( |
groups_lists |
(named |
id |
( |
is_event |
( |
indent_mod |
|
label_all |
( |
labelstr |
( |
lyt |
( |
method |
( |
na.rm |
( |
na_level |
|
na_str |
( |
nested |
( |
newpage |
( |
prune_zero_rows |
( |
riskdiff |
( |
rsp |
( |
section_div |
( |
show_labels |
( |
show_relative |
( |
strata |
( |
table_names |
( |
tte |
( |
var_labels |
( |
variables |
(named |
vars |
( |
var |
( |
x |
( |
ctrl_grp |
( |
Details
Although this function just returns NULL it has two uses, for
the tern users it provides a documentation of arguments that are
commonly and consistently used in the framework. For the developer it adds a
single reference point to import the roxygen argument description with:
@inheritParams proposal_argument_convention
Analyse Multiple Imputed Datasets
Description
This function takes multiple imputed datasets (as generated by the impute() function from the rbmi package) and runs an analysis function on each of them.
Usage
rbmi_analyse(
imputations,
fun = rbmi_ancova,
delta = NULL,
...,
cluster_or_cores = 1,
.validate = TRUE
)
Arguments
imputations |
An |
fun |
An analysis function to be applied to each imputed dataset. See details. |
delta |
A |
... |
Additional arguments passed onto |
cluster_or_cores |
( |
.validate |
( |
Details
This function works by performing the following steps:
Extract a dataset from the
imputationsobject.Apply any delta adjustments as specified by the
deltaargument.Run the analysis function
funon the dataset.Repeat steps 1-3 across all of the datasets inside the
imputationsobject.Collect and return all of the analysis results.
The analysis function fun must take a data.frame as its first
argument. All other options to rbmi_analyse() are passed onto fun
Value
An analysis object, as defined by rbmi, representing the desired
analysis applied to each of the imputed datasets in imputations.
Analysis of Covariance
Description
Performs an analysis of covariance between two groups returning the estimated "treatment effect" (i.e. the contrast between the two treatment groups) and the least square means estimates in each group.
Usage
rbmi_ancova(
data,
vars,
visits = NULL,
weights = c("counterfactual", "equal", "proportional_em", "proportional")
)
Arguments
data |
A |
vars |
A |
visits |
An optional character vector specifying which visits to
fit the ancova model at. If |
weights |
Character, either |
Details
The function works as follows:
Select the first value from
visits.Subset the data to only the observations that occurred on this visit.
Fit a linear model as
vars$outcome ~ vars$group + vars$covariates.Extract the "treatment effect" & least square means for each treatment group.
Repeat points 2-3 for all other values in
visits.
If no value for visits is provided then it will be set to
unique(data[[vars$visit]]).
In order to meet the formatting standards set by rbmi_analyse() the results will be collapsed
into a single list suffixed by the visit name, e.g.:
list( var_visit_1 = list(est = ...), trt_B_visit_1 = list(est = ...), lsm_A_visit_1 = list(est = ...), lsm_B_visit_1 = list(est = ...), var_visit_2 = list(est = ...), trt_B_visit_2 = list(est = ...), lsm_A_visit_2 = list(est = ...), lsm_B_visit_2 = list(est = ...), ... )
Please note that "trt" refers to the treatment effects, and "lsm" refers to the least
square mean results. In the above example vars$group has two factor levels A and B.
The new "var" refers to the model estimated variance of the residuals.
If you want to include interaction terms in your model this can be done
by providing them to the covariates argument of the set_vars() function from the rbmi package
e.g. set_vars(covariates = c("sex*age")).
Value
a list of variance (var_*), treatment effect (trt_*), and
least square mean (lsm_*) estimates for each visit, organized as
described in Details above.
Note
These functions have the rbmi_ prefix to distinguish them from the corresponding
rbmi package functions, from which they were copied from. Additional features here
include:
Support for more than two treatment groups.
Variance estimates are returned.
See Also
The set_vars() function from the rbmi package
Implements an Analysis of Covariance (ANCOVA)
Description
Performance analysis of covariance. See rbmi_ancova() for full details.
Usage
rbmi_ancova_single(
data,
outcome,
group,
covariates,
weights = c("counterfactual", "equal", "proportional_em", "proportional")
)
Arguments
data |
A |
outcome |
string, the name of the outcome variable in |
group |
string, the name of the group variable in |
covariates |
character vector containing the name of any additional covariates to be included in the model as well as any interaction terms. |
weights |
Character, either |
Details
-
groupmust be a factor variable with only 2 levels. -
outcomemust be a continuous numeric variable.
Value
a list containing var with variance estimates as well as
trt_* and lsm_* entries. See rbmi_ancova() for full details.
See Also
Examples
iris2 <- iris[iris$Species %in% c("versicolor", "virginica"), ]
iris2$Species <- factor(iris2$Species)
rbmi_ancova_single(iris2, "Sepal.Length", "Species", c("Petal.Length * Petal.Width"))
MMRM Analysis for Imputed Datasets
Description
Performs an MMRM for two or more groups returning the estimated 'treatment effect' (i.e. the contrast between treatment groups and the control group) and the least square means estimates in each group.
Usage
rbmi_mmrm(
data,
vars,
cov_struct = c("us", "toep", "cs", "ar1"),
visits = NULL,
weights = c("counterfactual", "equal"),
...
)
Arguments
data |
( |
vars |
( |
cov_struct |
( |
visits |
( |
weights |
( |
... |
additional arguments passed to |
Details
The function works as follows:
Optionally select the subset of the
datacorresponding to 'visits.Fit an MMRM as
vars$outcome ~ vars$group + vars$visit + vars$covariateswith the specified covariance structure for visits within subjects.Extract the 'treatment effect' & least square means for each treatment group vs the control group.
In order to meet the formatting standards set by the analyse() function from the rbmi package, the results will be collapsed into a single list suffixed by the visit name, e.g.:
list( var_B_visit_1 = list(est = ...), trt_B_visit_1 = list(est = ...), lsm_A_visit_1 = list(est = ...), lsm_B_visit_1 = list(est = ...), var_B_visit_2 = list(est = ...), trt_B_visit_2 = list(est = ...), lsm_A_visit_2 = list(est = ...), lsm_B_visit_2 = list(est = ...), ... )
Please note that 'trt' refers to the treatment effects, and 'lsm' refers to the least
square mean results. In the above example vars$group has two factor levels A and B.
The new 'var' refers to the model estimated variance of the residuals at the given
visit, together with the degrees of freedom (which is treatment group specific).
If you want to include additional interaction terms in your model this can be done
by providing them to the covariates argument of the set_vars() function from the rbmi package
e.g. set_vars(covariates = c('sex*age')).
Value
a list of variance (var_*), treatment effect (trt_*), and
least square mean (lsm_*) estimates for each visit, organized as
described in Details above.
Note
The group and visit interaction group:visit is not included by
default in the model, therefore please add that to covariates manually if
you want to include it. This will make sense in most cases.
See Also
The set_vars() function from the rbmi package
Extract Single Visit Information from a Fitted MMRM for Multiple Imputation Analysis
Description
Extracts relevant estimates from a given fitted MMRM. See rbmi_mmrm() for full details.
Usage
rbmi_mmrm_single_info(fit, visit_level, visit, group, weights)
Arguments
fit |
( |
visit_level |
( |
visit |
( |
group |
( |
weights |
( |
Value
a list with trt_*, var_* and lsm_* elements. See rbmi_mmrm for
full details.
See Also
Pool analysis results obtained from the imputed datasets
Description
Pool analysis results obtained from the imputed datasets
Usage
rbmi_pool(
results,
conf.level = 0.95,
alternative = c("two.sided", "less", "greater"),
type = c("percentile", "normal")
)
Arguments
results |
an analysis object created by analyse(). |
conf.level |
confidence level of the returned confidence interval. Must be a single number between 0 and 1. Default is 0.95. |
alternative |
a character string specifying the alternative hypothesis,
must be one of |
type |
a character string of either |
Details
This has been forked from the rbmi package, mainly to support in
addition the pooling of variance estimates. See pool() for more details.
Value
A list of class pool.
Add Overall Facet
Description
A function to help add an overall facet to your tables.
Usage
real_add_overall_facet(name, label)
Arguments
name |
( |
label |
( |
Value
Function usable directly as a split function.
Note
Current add_overall_facet is bugged. Can be used directly after it's fixed https://github.com/pharmaverse/rtables/issues/768
Examples
splfun <- make_split_fun(post = list(real_add_overall_facet("Total", "Total")))
Removal of Unwanted Column Counts
Description
Remove the N=xx column headers for specified span_label_var columns - default is 'rrisk_header'.
Usage
remove_col_count(obj, span_label_var = "rrisk_header")
Arguments
obj |
( |
span_label_var |
( |
Details
This works for only the lowest level of column splitting (since colcounts is used).
Value
TableTree object with column counts in specified columns removed.
Pruning function to remove specific rows of a table regardless of counts
Description
This function will remove all rows of a table based on the row text provided by the user.
Usage
remove_rows(removerowtext = NULL, reg_expr = FALSE)
Arguments
removerowtext |
( |
reg_expr |
( |
Value
Function that can be utilized as pruning function in prune_table.
Examples
ADSL <- data.frame(
USUBJID = c(
"XXXXX01", "XXXXX02", "XXXXX03", "XXXXX04", "XXXXX05",
"XXXXX06", "XXXXX07", "XXXXX08", "XXXXX09", "XXXXX10"
),
TRT01P = c(
"ARMA", "ARMB", "ARMA", "ARMB", "ARMB", "Placebo",
"Placebo", "Placebo", "ARMA", "ARMB"
),
Category = c(
"Cat 1", "Cat 2", "Cat 1", "Unknown", "Cat 2",
"Cat 1", "Unknown", "Cat 1", "Cat 2", "Cat 1"
),
SAFFL = c("N", "N", "N", "N", "N", "N", "N", "N", "N", "N"),
PKFL = c("N", "N", "N", "N", "N", "N", "N", "N", "N", "N")
)
ADSL <- ADSL |>
dplyr::mutate(TRT01P = as.factor(TRT01P))
lyt <- basic_table() |>
split_cols_by("TRT01P") |>
analyze(
"Category",
afun = a_freq_j,
extra_args = list(.stats = "count_unique_fraction")
)
result <- build_table(lyt, ADSL)
result
result <- prune_table(result, prune_func = remove_rows(removerowtext = "Unknown"))
result
Formatted Analysis Function for Comparative Statistic in Response Tables (RESP01)
Description
This function applies to a factor column called .var from df.
Usage
resp01_a_comp_stat_factor(df, .var, include, ...)
Arguments
df |
( |
.var |
( |
include |
( |
... |
see |
Value
The formatted result as rtables::rcell().
Examples
dm <- droplevels(subset(formatters::DM, SEX %in% c("F", "M")))
resp01_a_comp_stat_factor(
dm,
.var = "COUNTRY",
conf_level = 0.9,
include = c("USA", "CHN"),
arm = "SEX",
strata = "RACE",
stat = "comp_stat_ci",
methods = list(comp_stat_ci = "or_cmh"),
formats = list(
comp_stat_ci = jjcsformat_xx("xx.xx (xx.xx - xx.xx)"),
pval = jjcsformat_pval_fct(0.05)
)
)
Formatted Analysis Function for Comparative Statistic in Response Tables (RESP01)
Description
This function applies to a logical column called .var from df.
The response proportion is compared between the treatment arms identified
by column arm.
Usage
resp01_a_comp_stat_logical(
df,
.var,
conf_level,
include,
arm,
strata,
formats,
methods,
stat = c("comp_stat_ci", "pval")
)
Arguments
df |
( |
.var |
( |
conf_level |
( |
include |
( |
arm |
( |
strata |
( |
formats |
( |
methods |
( |
stat |
( |
Value
The formatted result as rtables::rcell().
See Also
resp01_a_comp_stat_factor() for the factor equivalent.
Examples
dm <- droplevels(subset(formatters::DM, SEX %in% c("F", "M")))
dm$RESP <- as.logical(sample(c(TRUE, FALSE), size = nrow(DM), replace = TRUE))
resp01_a_comp_stat_logical(
dm,
.var = "RESP",
conf_level = 0.9,
include = TRUE,
arm = "SEX",
strata = "RACE",
stat = "comp_stat_ci",
methods = list(comp_stat_ci = "or_cmh"),
formats = list(
comp_stat_ci = jjcsformat_xx("xx.xx (xx.xx - xx.xx)"),
pval = jjcsformat_pval_fct(0.05)
)
)
Formatted Analysis and Content Summary Function for Response Tables (RESP01)
Description
This function applies to both factor and logical columns called
.var from df. Depending on the position in the split, it returns the
right formatted results for the RESP01 and related layouts.
Usage
resp01_acfun(
df,
labelstr = NULL,
label = NULL,
.var,
.spl_context,
include_comp,
.alt_df,
conf_level,
arm,
strata,
formats,
methods
)
Arguments
df |
( |
labelstr |
( |
label |
( |
.var |
( |
.spl_context |
( |
include_comp |
( |
.alt_df |
( |
conf_level |
( |
arm |
( |
strata |
( |
formats |
( |
methods |
( |
Value
The formatted result as rtables::in_rows() result.
Examples
fake_spl_context <- data.frame(
cur_col_split_val = I(list(c(ARM = "A: Drug X", count_prop = "count_prop")))
)
dm <- droplevels(subset(DM, SEX %in% c("F", "M")))
resp01_acfun(
dm,
.alt_df = dm,
.var = "COUNTRY",
.spl_context = fake_spl_context,
conf_level = 0.9,
include_comp = c("USA", "CHN"),
arm = "SEX",
strata = "RACE",
methods = list(
comp_stat_ci = "or_cmh",
pval = "",
prop_ci = "wald"
),
formats = list(
prop_ci = jjcsformat_xx("xx.% - xx.%"),
comp_stat_ci = jjcsformat_xx("xx.xx (xx.xx - xx.xx)"),
pval = jjcsformat_pval_fct(0.05)
)
)
fake_spl_context2 <- data.frame(
cur_col_split_val = I(list(c(ARM = "Overall", comp_stat_ci = "comp_stat_ci")))
)
resp01_acfun(
dm,
.alt_df = dm,
.var = "COUNTRY",
.spl_context = fake_spl_context2,
conf_level = 0.9,
include_comp = c("USA", "CHN"),
arm = "SEX",
strata = "RACE",
methods = list(
comp_stat_ci = "or_cmh",
pval = "",
prop_ci = "wald"
),
formats = list(
prop_ci = jjcsformat_xx("xx.% - xx.%"),
comp_stat_ci = jjcsformat_xx("xx.xx (xx.xx - xx.xx)"),
pval = jjcsformat_pval_fct(0.05)
)
)
Content Row Function for Counts of Subgroups in Response Tables (RESP01)
Description
Content Row Function for Counts of Subgroups in Response Tables (RESP01)
Usage
resp01_counts_cfun(df, labelstr, .spl_context, .alt_df, label_fstr)
Arguments
df |
( |
labelstr |
( |
.spl_context |
( |
.alt_df |
( |
label_fstr |
( |
Value
The correct rtables::in_rows() result.
Examples
fake_spl_context <- data.frame(
cur_col_split_val = I(list(c(ARM = "A: Drug X", count_prop = "count_prop")))
)
resp01_counts_cfun(
df = DM,
labelstr = "Blue",
.spl_context = fake_spl_context,
.alt_df = DM,
label_fstr = "Color: %s"
)
Split Function Factory for the Response Tables (RESP01)
Description
The main purpose here is to have a column dependent split into either comparative statistic (relative risk or odds ratio with p-value) in the 'Overall' column, and count proportions and corresponding confidence intervals in the other treatment arm columns.
Usage
resp01_split_fun_fct(method = c("rr", "or_logistic", "or_cmh"), conf_level)
Arguments
method |
( |
conf_level |
( |
Value
A split function for use in the response table RESP01 and similar ones.
See Also
rtables::make_split_fun() describing the requirements for this kind of
post-processing function.
Examples
split_fun <- resp01_split_fun_fct(
method = "or_cmh",
conf_level = 0.95
)
Calculate results across binary-imputation scenarios
Description
Runs h_impute_analyze_resp() for each paired control and treatment response
probability, pools estimates across imputations using Rubin's rules, and
pools Wilson-Hilferty z statistics to obtain a p-value. A scenario where both
probabilities are zero or one is deterministic and is therefore analyzed
once rather than repeatedly imputed.
Usage
resp_multiple_imputation(
dat,
p_ctrl,
p_trt,
trtvar,
ctrlab,
trtlab,
respvar,
stratvar,
n_imputations,
pvalcat
)
Arguments
dat |
( |
p_ctrl |
( |
p_trt |
( |
trtvar |
( |
ctrlab |
( |
trtlab |
( |
respvar |
( |
stratvar |
( |
n_imputations |
( |
pvalcat |
(named |
Value
A tibble with one row per scenario. rd and rd_se are the pooled
risk-difference estimate and standard error; p_value and p_cat are the
pooled p-value and its category. marker_flag and effect_label contain
"*" when a deterministic scenario or a single-imputation p-value fallback
was used.
Examples
dat <- data.frame(
arm = rep(c("Control", "Treatment"), each = 4),
response = c(TRUE, FALSE, NA, TRUE, TRUE, FALSE, NA, FALSE),
strata = rep(c("A", "B"), 4)
)
pvalcat <- list("<0.05" = c(0, 0.05), ">=0.05" = c(0.05, 1))
set.seed(123)
resp_multiple_imputation(
dat,
p_ctrl = c(0, 0.25),
p_trt = c(1, 0.75),
trtvar = "arm",
ctrlab = "Control",
trtlab = "Treatment",
respvar = "response",
stratvar = "strata",
n_imputations = 5,
pvalcat = pvalcat
)
Count denom fraction statistic
Description
Derives the count_denom_fraction statistic (i.e., 'xx /xx (xx.x percent)' )
Summarizes the number of unique subjects with a response = 'Y' for a given variable
(e.g. TRTEMFL) within each category of another variable (e.g., SEX).
Note that the denominator is derived using input df,
in order to have these aligned with alt_source_df, it is expected that df includes all subjects.
Usage
response_by_var(
df,
labelstr = NULL,
.var,
.N_col,
resp_var = NULL,
id = "USUBJID",
.format = jjcsformat_count_denom_fraction,
...
)
Arguments
df |
( |
labelstr |
( |
.var |
( |
.N_col |
( |
resp_var |
( |
id |
( |
.format |
( |
... |
Additional arguments passed to the function. |
Details
This is an analysis function for use within analyze. Arguments
df, .var will be populated automatically by rtables during
the tabulation process.
Value
a RowsVerticalSection for use by the internal tabulation machinery of rtables
Examples
library(dplyr)
ADAE <- data.frame(
USUBJID = c(
"XXXXX01", "XXXXX02", "XXXXX03", "XXXXX04", "XXXXX05",
"XXXXX06", "XXXXX07", "XXXXX08", "XXXXX09", "XXXXX10"
),
SEX_DECODE = c(
"Female", "Female", "Male", "Female", "Male",
"Female", "Male", "Female", "Male", "Female"
),
TRT01A = c(
"ARMA", "ARMB", "ARMA", "ARMB", "ARMB",
"Placebo", "Placebo", "Placebo", "ARMA", "ARMB"
),
TRTEMFL = c("Y", "Y", "N", "Y", "Y", "Y", "Y", "N", "Y", "Y")
)
ADAE <- ADAE |>
mutate(
TRT01A = as.factor(TRT01A),
SEX_DECODE = as.factor(SEX_DECODE)
)
lyt <- basic_table() |>
split_cols_by("TRT01A") |>
analyze(
vars = "SEX_DECODE",
var_labels = "Sex, n/Ns (%)",
show_labels = "visible",
afun = response_by_var,
extra_args = list(resp_var = "TRTEMFL"),
nested = FALSE
)
result <- build_table(lyt, ADAE)
result
Extract the right-hand side of a formula
Description
Extract the right-hand side of a formula
Usage
rightside(x)
Arguments
x |
( |
Value
(character(1)) The right-hand side of the formula.
Examples
rightside(y ~ x1 + x2)
Removal of Levels
Description
Custom function for removing level inside pre step in make_split_fun.
Usage
rm_levels(excl)
Arguments
excl |
( |
Value
A function implementing pre-processing split behavior (for use in
make_split_fun(pre = ) which removes the levels in excl from the data
before facets are generated.
rm_other_facets_fact
Description
rm_other_facets_fact
Usage
rm_other_facets_fact(nm)
Arguments
nm |
character. names of facets to keep. all other facets will be removed |
Value
a function suitable for use within the post portion make_split_fun
Junco Extended ANCOVA Function
Description
Extension to tern:::s_ancova, 3 extra statistics are returned:
-
lsmean_se: Marginal mean and estimated SE in the group. -
lsmean_ci: Marginal mean and associated confidence interval in the group. -
lsmean_diff_with_ci: Difference in mean and associated confidence level in one combined statistic. In addition, the LS mean weights can be specified. In addition, also a NULL .ref_group can be specified, the lsmean_diff related estimates will be returned as NA.
Usage
s_ancova_j(
df,
.var,
.df_row,
variables,
.ref_group,
.in_ref_col,
conf_level,
interaction_y = FALSE,
interaction_item = NULL,
weights_emmeans = "counterfactual",
method_combo = c("contrasts", "collapse"),
weights_combo = NULL
)
Arguments
df |
( |
.var |
( |
.df_row |
( |
variables |
(named
|
.ref_group |
( |
.in_ref_col |
( |
conf_level |
( |
interaction_y |
( |
interaction_item |
( |
weights_emmeans |
( |
method_combo |
(
For more information see the vignette |
weights_combo |
(
|
Value
Returns a named list of 8 statistics (3 extra compared to tern:::s_ancova()).
See Also
Other Inclusion of ANCOVA Functions:
a_summarize_ancova_j(),
a_summarize_aval_chg_diff_j()
Examples
library(dplyr)
library(tern)
df <- iris |> filter(Species == "virginica")
.df_row <- iris
.var <- "Petal.Length"
variables <- list(arm = "Species", covariates = "Sepal.Length * Sepal.Width")
.ref_group <- iris |> filter(Species == "setosa")
conf_level <- 0.95
s_ancova_j(df, .var, .df_row, variables, .ref_group, .in_ref_col = FALSE, conf_level)
s_coxph_hr
Description
s_coxph_hr Use
tern::s_coxph_pairwise instead, and use tern::coxph_pairwise() as
the layout-level wrapper.
Usage
s_coxph_hr(
df,
.var,
ref_path,
.spl_context,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
Arguments
df |
( |
.var |
( |
ref_path |
( |
.spl_context |
( |
... |
Additional arguments passed to the statistics function. |
.stats |
( |
.formats |
( |
.labels |
( |
.indent_mods |
( |
s_kaplan_meier
Description
Use
tern::s_surv_time() instead.
Usage
s_kaplan_meier(df, .var, is_event, control = control_surv_time())
s_function for proportion of factor levels
Description
A simple statistics function which prepares the numbers with percentages in the required format. The denominator here is from the alternative counts data set in the given row and column split.
If a total row is shown, then here just the total number is shown (without 100%).
Usage
s_proportion_factor(
x,
.alt_df,
use_alt_counts = TRUE,
show_total = c("none", "top", "bottom"),
total_label = "Total"
)
Arguments
x |
( |
.alt_df |
( |
use_alt_counts |
( |
show_total |
( |
total_label |
( |
Value
The rtables::in_rows() result with the proportion statistics.
See Also
s_proportion_logical() for tabulating logical x.
s_function for proportion of TRUE in logical vector
Description
A simple statistics function which prepares the numbers with percentages in the required format. The denominator here is from the alternative counts data set in the given row and column split.
Usage
s_proportion_logical(x, label = "Responders", .alt_df)
Arguments
x |
( |
label |
( |
.alt_df |
( |
Value
The rtables::in_rows() result with the proportion statistics.
See Also
s_proportion_factor() for tabulating factor x.
Descriptive Statistics for Univariate Data with Optional Reference Comparison
Description
Computes descriptive statistics for a single variable df[[.var]] using
tern::s_summary(), which dispatches type-specific methods depending on the
S3 class of the input (e.g., character, factor, logical, numeric).
Optionally, it computes estimates and associated inferential statistics for
the difference in population means between two underlying distributions,
based on observed samples df[[.var]] and .ref_group[[.var]] using
s_diff_means().
These statistics are applicable only to numeric data.
Usage
s_summary_diff(
df,
.var,
.stats = NULL,
.ref_group = NULL,
.in_ref_col = FALSE,
control = tern::control_analyze_vars(),
...
)
Arguments
df |
( |
.var |
( |
.stats |
( |
.ref_group |
( |
.in_ref_col |
( |
control |
( |
... |
Additional named arguments passed to |
Value
A named list with the requested statistics.
Author(s)
WW
Examples
df <- data.frame(
USUBJID = c("X01", "X02", "X03", "X04", "X05"),
TRT01A = rep("ARM_A", 5),
PARAMCD = rep("SYSBP", 5),
AVISIT = rep("Visit 1", 5),
CHG = c(4, 1, -1, 9, -2)
)
df
rg <- data.frame(
USUBJID = c("X06", "X07", "X08", "X09", "X10"),
TRT01A = rep("Placebo", 5),
PARAMCD = rep("SYSBP", 5),
AVISIT = rep("Visit 1", 5),
CHG = c(-2, 6, -2, 5, 2)
)
rg
.stats <- c("n", "mean_sd", "diff_means_n1", "diff_means_n2", "diff_means_est_ci")
# With reference group.
s_summary_diff(df, "CHG", .stats, rg)
# Using df as reference.
s_summary_diff(df, "CHG", .stats, df, .in_ref_col = TRUE)
Safe Conversion to Logical Vector
Description
Safe Conversion to Logical Vector
Usage
safe_as_logical(x, na.rm = FALSE)
Arguments
x |
( |
na.rm |
( |
Value
A logical vector corresponding to the input x. If the conversion introduces
unexpected NA values, an error is raised.
Safely Prune Table With Empty Table Message If Needed
Description
Safely Prune Table With Empty Table Message If Needed
Usage
safe_prune_table(
tt,
prune_func = prune_empty_level,
stop_depth = NA,
empty_msg = " - No Data To Display - ",
spancols = FALSE
)
Arguments
tt |
( |
prune_func |
( |
stop_depth |
( |
empty_msg |
( |
spancols |
( |
Value
tt pruned based on the arguments, or, if
pruning would remove all rows, a TableTree with the
same column structure, and one row containing the
empty message spanning all columns.
Examples
prfun <- function(tt) TRUE
lyt <- basic_table() |>
split_cols_by("ARM") |>
split_cols_by("STRATA1") |>
split_rows_by("SEX") |>
analyze("AGE")
tbl <- build_table(lyt, ex_adsl)
safe_prune_table(tbl, prfun)
Set Output Titles
Description
Retrieves titles and footnotes from the list specified in the titles argument and appends them to the TableTree specified in the obj argument.
Usage
set_titles(obj, titles)
Arguments
obj |
( |
titles |
( |
Value
The TableTree object specified in the obj argument, with titles and footnotes appended.
Create Column Structure for a J&J-Style Shift Table
Description
Create Column Structure for a J&J-Style Shift Table
Usage
shift_tbl_col_struct(lyt, var, span_lbl = "Baseline", .outer_spl_var = var)
Arguments
lyt |
( |
var |
( |
span_lbl |
( |
.outer_spl_var |
( |
Details
This function creates a column structure akin to the following
(with Grade 1 through Grade 5 representing the levels of var):
Baseline N Grade 1 Grade 2 Grade 3 Grade 4 Grade 5 Total ——————————————————————————————————————————————————————————————
Value
lyt updated with the specified shift table column structure.
See Also
Other std_col_struct:
grouped_cols_w_diffs(),
make_multicomp_splfun()
Examples
shift_data <- data.frame(
BASE = factor(c("Grade 1", "Grade 2", "Grade 3")),
CHG = c("Improved", "Stable", "Worsened")
)
lyt <- basic_table() |>
shift_tbl_col_struct("BASE") |>
analyze("CHG", afun = function(x, ...) length(x))
build_table(lyt, shift_data)
Shortcut for Creating Custom Column Splits
Description
This is a shortcut for a common use of rtables::make_split_result() where you need to create
custom column splits with different labels but using the same full dataset for each column.
It automatically sets up the values, datasplit (using the same full dataset for each column),
and subset_exprs (using TRUE for all subsets) parameters for make_split_result().
Usage
short_split_result(..., fulldf)
Arguments
... |
sequence of named labels for the columns. |
fulldf |
( |
Value
The result from rtables::make_split_result().
Colwidths for all columns to be forced on one page.
Description
Colwidths for all columns to be forced on one page.
Usage
smart_colwidths_1page(
tt,
fontspec,
col_gap = 6L,
rowlabel_width = inches_to_spaces(2, fontspec),
print_width_ins = ifelse(landscape, 11, 8.5) - 2.12,
landscape = FALSE,
lastcol_gap = TRUE
)
Arguments
tt |
( |
fontspec |
( |
col_gap |
( |
rowlabel_width |
( |
print_width_ins |
( |
landscape |
( |
lastcol_gap |
( |
Standard All vs Some (e.g. Related AEs) column structure
Description
Standard All vs Some (e.g. Related AEs) column structure
Usage
some_v_all_col_struct(
lyt,
colspan_trt_map = NULL,
combo_map_df = NULL,
trtvar = names(colspan_trt_map)[2],
subgrp_var = NULL,
subgrp_lbl = subgrp_var,
all_lbl,
subgrp_lvls,
.pre = list(),
.post = list()
)
Arguments
lyt |
( |
colspan_trt_map |
( |
combo_map_df |
( |
trtvar |
( |
subgrp_var |
( |
subgrp_lbl |
( |
all_lbl |
( |
subgrp_lvls |
( |
.pre |
( |
.post |
( |
Details
This column structure generating function is for comparing a single portion of the data (as represented by
level(s) of subgrp_var) against the full data, comparison of AE counts to treatment-related AE counts
being a motivating example.
Examples
library(junco)
dat <- create_colspan_var(
data.frame(
TRT01A = factor(rep(c("Placebo", "Active 1", "Active 2"), each = 5)),
GRADE = factor(rep(paste("Grade ", 1:5), 3))
),
non_active_grp = "Placebo",
non_active_grp_span_lbl = "Control",
active_grp_span_lbl = "Active Treatment",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
colspan_trt_map <- create_colspan_map(
dat,
non_active_grp = "Placebo",
non_active_grp_span_lbl = "Control",
active_grp_span_lbl = "Active Treatment",
colspan_var = "colspan_trt",
trt_var = "TRT01A"
)
lyt <- basic_table() |>
some_v_all_col_struct(
colspan_trt_map,
subgrp_var = "GRADE",
subgrp_lvls = c("Grade 4", "Grade 5"),
subgrp_lbl = "High Grade",
all_lbl = "All Grades")
build_table(lyt, dat)
Function factory to be used as Post-processing split function for setup of stats in column structure
Description
This helper is designed to be used in the post argument of
rtables::make_split_fun() to expand a column facet (e.g. AVAL/BASE/CHG)
into the specific statistics to be analyzed for each subfacet. It returns a
split result instructing rtables which values/labels/subsets to create.
Typical usage:
construct a split function like
mysplitfun <- rtables::make_split_fun(post = list(stats_in_cols_setup()))
Then usemysplitfunin your table layout where you split columns by a variable whose levels are one of "AVAL", "BASE", or "CHG" and want to analyze different statistics for each.column layout setup from
rtables::split_cols_by_multivar(), followed by split_cols_by usingstats_in_cols_setupin conjunction with an analyze call withafun=column_stats()
See examples for typical usage.
Usage
stats_in_cols_setup(
stats_list = list(AVAL = c("n", "mean", "sd", "se", "median", "min", "max"), BASE =
c("mean_sd"), CHG = c("n", "mean", "sd", "se", "median", "min", "max")),
statlbls_list = c(median = "Med", min = "Min", max = "Max", mean_sd = "Base Mean (SD)",
n = "N")
)
Arguments
stats_list |
|
statlbls_list |
“ Named vector with labels to use for the statistic in column header. If NULL, or a statistic name is not included, the default label for the statistic will be used. |
Value
A function that can be used inside rtables::make_split_result()
statistics for the current column level.
See Also
rtables::make_split_fun(), rtables::make_split_result().
Examples
# example code
library(dplyr)
advs <- ex_advs |>
filter(AVISIT %in% toupper(c("Screening", "Baseline", "Week 1 Day 8", "Week 2 Day 15"))) |>
mutate(AVISIT = droplevels(AVISIT))
mysplitfun <- make_split_fun(
post = list(stats_in_cols_setup())
)
lyt <- basic_table() |>
split_cols_by_multivar(
c("AVAL", "BASE", "CHG"),
varlabels = c("Visit Values", " ", "Change from Baseline")
) |>
split_cols_by("STUDYID", split_fun = mysplitfun) |>
split_rows_by("PARAM") |>
split_rows_by("ARMCD", labels_var = "ARM") |>
analyze("AVISIT",
afun = column_stats,
extra_args = list(exclude_visits = toupper(c("Baseline", "Screening")))
)
result <- build_table(lyt, advs, round_type = "sas")
head(result, 20)
Strictly Match a Value in a Character Vector
Description
Finds a unique match of a value in either the odd or even positions of a character vector. An error is raised if no match or more than one match is found in the selected positions.
Usage
strict_match(x, y, odd = TRUE)
Arguments
x |
( |
y |
( |
odd |
( |
Value
An integer containing the unique position of x in y.
Author(s)
WW
Examples
## Not run:
strict_match("A", c("A", "Placebo"))
strict_match("SEX", c("SomeVar", "SomeVal", "SEX", "Male"))
strict_match("ARM", c("SEX", "Male"))
strict_match("Male", c("SEX", "Male"))
strict_match("ARM", c("ARM", "Placebo", "ARM", "Active"))
## End(Not run)
Title Case Conversion
Description
Convert strings to title case (first letter of each word capitalized), with the option to keep specified words, such as conjunctions, lowercase.
Usage
string_to_title(x, lowercase_words = NULL)
Arguments
x |
( |
lowercase_words |
( |
Value
x converted to title case, with words specified in
lowercase_words kept lowercase.
Examples
x <- c("THIS IS an eXaMple", "statement TO CAPItaliZe")
string_to_title(x)
string_to_title(x, c("is", "an", "to"))
x <- factor(
c("OPTIMAL DOSE", "UNDERDOSE"),
levels = c("OPTIMAL DOSE", "UNDERDOSE", "OVERDOSE")
)
string_to_title(x)
Layout Generating Function for TEFOS03 and Related Cox Regression Layouts
Description
Layout Generating Function for TEFOS03 and Related Cox Regression Layouts
Usage
summarize_coxreg_multivar(
lyt,
var,
variables,
control = control_coxreg(),
formats = list(coef_se = jjcsformat_xx("xx.xx (xx.xx)"), hr_est =
jjcsformat_xx("xx.xx"), hr_ci = jjcsformat_xx("(xx.xx, xx.xx)"), pval =
jjcsformat_pval_fct(0))
)
Arguments
lyt |
( |
var |
( |
variables |
(named |
control |
( |
formats |
(named |
Value
lyt modified to add the desired cox regression table section.
Examples
anl <- tern::tern_ex_adtte |>
dplyr::mutate(EVENT = 1 - CNSR)
variables <- list(
time = "AVAL",
event = "EVENT",
arm = "ARM",
covariates = c("SEX", "AGE")
)
basic_table() |>
summarize_coxreg_multivar(
var = "STUDYID",
variables = variables
) |>
build_table(df = anl)
Dynamic tabulation of MMRM results with tables
Description
These functions can be used to produce tables for MMRM results, within tables which are split by arms and visits. This is helpful when higher-level row splits are needed (e.g. splits by parameter or subgroup).
Usage
s_summarize_mmrm(
df,
.var,
variables,
ref_levels,
.spl_context,
alternative = c("two.sided", "less", "greater"),
show_relative = c("reduction", "increase"),
...
)
a_summarize_mmrm(
df,
.var,
.spl_context,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
a_summarize_mmrm_with_exclude(
df,
.var,
exclude_levels,
.spl_context,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
Arguments
df |
( |
.var |
( |
variables |
(named |
ref_levels |
( |
.spl_context |
( |
alternative |
( |
show_relative |
( |
... |
eventually passed to |
.stats |
( |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
exclude_levels |
( |
Value
-
a_summarize_mmrm()returns the corresponding list with formattedrtables::CellValue().
Functions
-
s_summarize_mmrm(): Statistics function which is extracting estimates, not including any results when in the reference visit, and only showing LS mean estimates when in the reference arm and not in reference visit. It usess_lsmeans()for the final processing. -
a_summarize_mmrm(): Formatted analysis function which is used asafun. -
a_summarize_mmrm_with_exclude(): Wrapper for theafunwhich can exclude row split levels from producing the analysis. These have to be specified in theexclude_levelsargument, see?do_exclude_splitfor details.
Examples
set.seed(123)
longdat <- data.frame(
ID = rep(DM$ID, 5),
AVAL = c(
rep(0, nrow(DM)),
rnorm(n = nrow(DM) * 4)
),
VISIT = factor(rep(paste0("V", 0:4), each = nrow(DM)))
) |>
dplyr::inner_join(DM, by = "ID")
basic_table() |>
split_rows_by("VISIT") |>
split_cols_by("ARM") |>
analyze(
vars = "AVAL",
afun = a_summarize_mmrm,
na_str = tern::default_na_str(),
show_labels = "hidden",
extra_args = list(
variables = list(
covariates = c("AGE"),
id = "ID",
arm = "ARM",
visit = "VISIT"
),
conf_level = 0.9,
cor_struct = "toeplitz",
ref_levels = list(VISIT = "V0", ARM = "B: Placebo")
)
) |>
build_table(longdat) |>
prune_table(all_zero)
Layout Creating Function Adding Row Counts
Description
This is a simple wrapper of rtables::summarize_row_groups() and the main
additional value is that we can choose whether we want to use the alternative
(usually ADSL) data set for the counts (default) or use the original data set.
Usage
summarize_row_counts(lyt, label_fstr = "%s", alt_counts = TRUE)
Arguments
lyt |
( |
label_fstr |
( |
alt_counts |
( |
Value
A modified layout where the latest row split now has a row group summaries (as created by rtables::summarize_row_groups for the counts).
Examples
basic_table() |>
split_cols_by("ARM") |>
add_colcounts() |>
split_rows_by("RACE", split_fun = drop_split_levels) |>
summarize_row_counts(label_fstr = "RACE value - %s") |>
analyze("AGE", afun = list_wrap_x(summary), format = "xx.xx") |>
build_table(DM, alt_counts_df = rbind(DM, DM))
Wrappers Around tern::a_summary() with Optional Subsetting and Labels
Description
These wrappers around tern::a_summary() allow optional row subsetting
using a logical expression evaluated in the context of the input data frame.
a_summary_subset() is an rtables analysis function (see
rtables::analyze()), while c_summary_subset_label() is a content row
function (see rtables::summarize_row_groups()) that may optionally
append a label to the resulting content row.
Usage
a_summary_subset(df, .var, filter_expr, ...)
c_summary_subset_label(
df,
labelstr,
.var,
filter_expr,
label = "",
label_indent_mod = 0L,
...
)
Arguments
df |
( |
.var |
( |
filter_expr |
( In the current implementation, variables used in the expression can only
be column names of The expression must evaluate to a logical vector whose length is exactly
equal to |
... |
Additional arguments passed to |
labelstr |
( |
label |
( |
label_indent_mod |
( |
Details
tern::a_summary() is a formatted analysis function that computes summary
statistics for a single variable. In typical use within the rtables
framework, the analysis variable is first extracted from a data frame and
then passed to tern::a_summary() as a standalone vector.
The a_summary_subset() and c_summary_subset_label() wrappers extend
this behavior by:
accepting a data frame (
df) as input,optionally subsetting rows using a logical expression,
extracting the analysis variable
.varafter subsetting,and passing the resulting vector to
tern::a_summary().
Value
Returns the same type of object as tern::a_summary().
Functions
-
a_summary_subset(): Analysis function with optional subsetting. -
c_summary_subset_label(): Content row function with optional subsetting and an optional label prepended to the resulting content row usingprepend_label_cell().
Author(s)
WW
See Also
Examples
## Analysis function:
df <- data.frame(
ID = 1:8,
AGE = c(34, NA, 52, 45, 50, NA, 41, 29),
AVAL = c(1.2, 3, -1.5, 0.8, 3.5, 2, -1.1, 0.3)
)
df
stats <- c("n", "sum")
tern::a_summary(df$AVAL, .stats = stats)
a_summary_subset(df, "AVAL", expression(!is.na(AGE)), .stats = stats)
a_summary_subset(df, "AVAL", expression(AGE > 30 & AVAL > 0), .stats = stats)
## Content row function:
df <- data.frame(
USUBJID = rep(1:6, each = 2),
AVISIT = rep(c("Baseline", "Day 1"), 6),
AVAL = c(1, 3, 2, 9, 13, 19, 15, 23, 43, 56, 24, 32),
ABLFL = rep(c(TRUE, FALSE), 6),
BASE = rep(c(1, 2, 13, 15, 43, 24), each = 2),
CHG = c(0, 2, 0, 7, 0, 6, 0, 8, 0, 13, 0, 8)
)
df
c_summary_subset_label(
df = df,
.var = "BASE",
filter_expr = expression(ABLFL),
label = "Baseline",
.stats = c("n", "mean_sd")
)
Tabulation of Least Square Means Results
Description
These functions can be used to produce tables from LS means, e.g. from fit_mmrm_j()
or fit_ancova().
Usage
## S3 method for class 'tern_model'
tidy(x, ...)
s_lsmeans(
df,
.in_ref_col,
alternative = c("two.sided", "less", "greater"),
show_relative = c("reduction", "increase")
)
a_lsmeans(
df,
ref_path,
.spl_context,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
Arguments
x |
( |
... |
additional arguments for the lower level functions. |
df |
( |
.in_ref_col |
( |
alternative |
( |
show_relative |
( |
ref_path |
( |
.spl_context |
( |
.stats |
( |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
Value
For
s_lsmeans, a list containing the same statistics returned by tern.mmrm::s_mmrm_lsmeans, with the additionaldiff_mean_est_cithree-dimensional statistic.For
a_lsmeans, aVertalRowsSectionas returned by rtables::in_rows.
Functions
-
tidy(tern_model): Helper method (forbroom::tidy()) to prepare adata.framefrom antern_modelobject containing the least-squares means and contrasts. -
s_lsmeans(): Statistics function which is extracting estimates from a tidied least-squares means data frame. -
a_lsmeans(): Formatted Analysis function to be used asafun
Note
These functions have been forked from the tern.mmrm package. Additional features
are:
Additional
ref_pathargument for tern.mmrm::summarize_lsmeans().The function is more general in that it also works for LS means results from ANCOVA
Additional statistic
diff_mean_est_ciis returnedP-value sidedness can be chosen
Examples
result <- fit_mmrm_j(
vars = list(
response = "FEV1",
covariates = c("RACE", "SEX"),
id = "USUBJID",
arm = "ARMCD",
visit = "AVISIT"
),
data = mmrm::fev_data,
cor_struct = "unstructured",
weights_emmeans = "equal"
)
df <- broom::tidy(result)
s_lsmeans(df[8, ], .in_ref_col = FALSE)
s_lsmeans(df[8, ], .in_ref_col = FALSE, alternative = "greater", show_relative = "increase")
dat_adsl <- mmrm::fev_data |>
dplyr::select(USUBJID, ARMCD) |>
unique()
basic_table() |>
split_cols_by("ARMCD") |>
add_colcounts() |>
split_rows_by("AVISIT") |>
analyze(
"AVISIT",
afun = a_lsmeans,
show_labels = "hidden",
na_str = tern::default_na_str(),
extra_args = list(
.stats = c(
"n",
"adj_mean_se",
"adj_mean_ci",
"diff_mean_se",
"diff_mean_ci"
),
.labels = c(
adj_mean_se = "Adj. LS Mean (Std. Error)",
adj_mean_ci = "95% CI",
diff_mean_ci = "95% CI"
),
.formats = c(adj_mean_se = jjcsformat_xx("xx.x (xx.xx)")),
alternative = "greater",
ref_path = c("ARMCD", result$ref_level)
)
) |>
build_table(
df = broom::tidy(result),
alt_counts_df = dat_adsl
)
Tabulation of RBMI Results
Description
These functions can be used to produce tables from RBMI.
Usage
h_tidy_pool(x, visit_name, group_names)
s_rbmi_lsmeans(df, .in_ref_col, show_relative = c("reduction", "increase"))
a_rbmi_lsmeans(
df,
ref_path,
.spl_context,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL
)
Arguments
x |
( |
visit_name |
( |
group_names |
( |
df |
( |
.in_ref_col |
( |
show_relative |
( |
ref_path |
( |
.spl_context |
( |
... |
additional arguments for the lower level functions. |
.stats |
( |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
Value
-
h_tidy_pool()returns adata.framewith results of pooled analysis for a single visit.
-
s_rbmi_lsmeans()returns a list of statistics extracted from a tidied LS means data frame.
Functions
-
h_tidy_pool(): Helper function to produce data frame with results of pool for a single visit. -
s_rbmi_lsmeans(): Statistics function which is extracting estimates from a tidied RBMI results data frame. -
a_rbmi_lsmeans(): Formatted Analysis function which is used asafun.
Note
These functions have been forked from tern.rbmi. Additional features are:
Additional
ref_pathargument.Extraction of variance statistics in the
tidy()method.Adapted to
rbmiforked functions update with more than two treatment groups.
Analysis Function for TEFOS03 and Related Table Layouts
Description
Analysis Function for TEFOS03 and Related Table Layouts
Usage
tefos03_afun(df, .var, .spl_context, variables, control, formats)
Arguments
df |
( |
.var |
( |
.spl_context |
( |
variables |
( |
control |
( |
formats |
( |
First Level Column Split Function for TEFOS03 (mmy) Table Layout
Description
First Level Column Split Function for TEFOS03 (mmy) Table Layout
Usage
tefos03_first_post_fun(ret, spl, fulldf, .spl_context)
See Also
rtables::make_split_fun() for details.
Second Level Column Split Function Factory for TEFOS03 (mmy) Table Layout
Description
Second Level Column Split Function Factory for TEFOS03 (mmy) Table Layout
Usage
tefos03_second_split_fun_fct(conf_level)
Arguments
conf_level |
( |
Value
Split function to use in the TEFOS03 (mmy) and related table layouts.
See Also
tefos03_first_post_fun() for the first level split.
Get default statistical methods and their associated formats, labels, and indent modifiers
Description
Usage
tern_get_stats(
method_groups = "analyze_vars_numeric",
stats_in = NULL,
custom_stats_in = NULL,
add_pval = FALSE,
tern_defaults = tern_default_stats
)
tern_get_formats_from_stats(
stats,
formats_in = NULL,
levels_per_stats = NULL,
tern_defaults = tern_default_formats
)
tern_get_labels_from_stats(
stats,
labels_in = NULL,
levels_per_stats = NULL,
label_attr_from_stats = NULL,
tern_defaults = tern_default_labels
)
tern_get_indents_from_stats(
stats,
indents_in = NULL,
levels_per_stats = NULL,
tern_defaults = stats::setNames(as.list(rep(0L, length(stats))), stats)
)
tern_default_labels
Functions
-
tern_get_stats(): Get statistics available for a given method group (analyze function). -
tern_get_formats_from_stats(): Get formats corresponding to a list of statistics. -
tern_get_labels_from_stats(): Get labels corresponding to a list of statistics. -
tern_get_indents_from_stats(): Get row indent modifiers corresponding to a list of statistics/rows. -
tern_default_labels: Namedcharactervector of default labels fortern. This is only copied here from the latest GitHub version, because otherwise a tern test fails.
Note
These functions have been copied from the tern package file
utils_default_stats_formats_labels.R from GitHub development version 0.9.7.9017.
Slight modifications have been applied to enhance functionality:
-
tern_get_statsadded thetern_statsargument to avoid hardcoding within the function's body. -
tern_get_labels_from_statsis more careful when receiving partiallabels_inand partiallabel_attr_from_stats.
Once these features are included in the tern package, this file could be removed from
the junco package, and the functions could be used from the tern namespace directly.
Test of Proportion Difference with Method Selection Based on the Mantel-Fleiss Criterion
Description
Tests the difference in response proportions between a non-reference group and a reference group for stratified data. The test method is selected based on the Mantel-Fleiss (MF) criterion.
When the Mantel-Fleiss criterion is satisfied, a Cochran-Mantel-Haenszel
(CMH)-type test is performed using the method specified by mf_method.
When the criterion is not satisfied, Fisher's exact test is used instead.
Usage
a_test_proportion_diff_mf(
df,
.var,
.in_ref_col = NULL,
.ref_group = NULL,
val = TRUE,
variables = list(strata = NULL),
na.rm = FALSE,
alternative = c("two.sided", "less", "greater"),
mf_method = c("cmh", "cmh_sato", "cmh_wh"),
mf_threshold = NULL,
...,
.stats = NULL,
.formats = NULL,
.labels = NULL,
.indent_mods = NULL,
exact_footnote = rtables::RefFootnote(note = tern::d_test_proportion_diff(method =
"fisher", method_only = TRUE), index = 1L, symbol = "+")
)
s_test_proportion_diff_mf(
df,
.var,
.in_ref_col = NULL,
.ref_group = NULL,
val = TRUE,
variables = list(strata = NULL),
na.rm = FALSE,
alternative = c("two.sided", "less", "greater"),
mf_method = c("cmh", "cmh_sato", "cmh_wh"),
mf_threshold = NULL
)
Arguments
df |
( |
.var |
( |
.in_ref_col |
( |
.ref_group |
( |
val |
( |
variables |
( |
na.rm |
( This argument is passed unchanged to the |
alternative |
( |
mf_method |
( |
mf_threshold |
( |
... |
additional arguments for the lower level functions. |
.stats |
(character) |
.formats |
(named |
.labels |
(named |
.indent_mods |
(named |
exact_footnote |
( |
Details
The data are prepared by tern::h_prepare_rsp_table(), which constructs the
response vector, group indicator, optional strata variable, and the
corresponding 2 x 2 contingency table(s). When multiple strata variables are
supplied, the cross-combinations of their levels define the analysis strata.
The response variable is converted to a binary response according to val.
The analysis compares the response proportion in the non-reference group with
that in the reference group. The difference is calculated as the
non-reference group minus the reference group.
When strata are provided and the Mantel-Fleiss criterion is satisfied, the
selected CMH test tern::prop_cmh() is used to obtain the p-value for the
test of the difference in response proportions. The available
Cochran-Mantel-Haenszel tests are:
-
"cmh": Stratified Cochran-Mantel-Haenszel test. -
"cmh_sato": Stratified CMH test using the Sato variance estimator. -
"cmh_wh": Stratified CMH test using the Wilson-Hilferty transformation.
See tern::prop_cmh() for more details and references.
When strata are not specified, or when strata are specified but the
Mantel-Fleiss criterion is not satisfied or cannot be evaluated (e.g., when
none of the strata contain any observed values), Fisher's exact test
tern::prop_fisher() is used instead.
The Mantel-Fleiss criterion is evaluated using tern::mantel_fleiss_crit().
The statistics function s_test_proportion_diff_mf() follows the usage and
output of tern::s_test_proportion_diff() but removes the method argument
and selects internally between a Cochran-Mantel-Haenszel-type test and
Fisher's exact test based on the Mantel-Fleiss criterion.
Value
-
a_test_proportion_diff_mf()returns the correspondingRowsVerticalSectionobject with formatted results.
-
s_test_proportion_diff_mf()returns a list containing:pval(numeric(1)ornumeric(0))P-value from the test, or
numeric(0)when the function is evaluated for the reference column (.in_ref_colis NULL or.in_ref_colisTRUE).executed_method(character(1))Name of the test actually used for the analysis. Takes the value
NA_character_when the function is evaluated for the reference column (.in_ref_colisNULLor.in_ref_colisTRUE). Otherwise, identifies the method used:"cmh","cmh_sato","cmh_wh", or"fisher". Formatted analysis functions can use this value to determine whether an appropriate footnote should be added.
Functions
-
a_test_proportion_diff_mf(): Formatted analysis function used asafunto test the difference in response proportions, with method selection based on the Mantel-Fleiss criterion. -
s_test_proportion_diff_mf(): Statistics function testing the difference in response proportions. When strata variables are provided and the Mantel-Fleiss criterion is satisfied, the CMH testtern::prop_cmh()is used, with the values of thediff_seandtransformarguments determined bymf_method. Otherwise, i.e., when strata variables are not provided, or when strata variables are provided but the Mantel-Fleiss criterion is not satisfied or cannot be evaluated, Fisher's exact testtern::prop_fisher()is used.
Author(s)
WW
See Also
proportion_diff_mf, cond_proportion_j()
Examples
n <- 100 # Number of observations.
set.seed(123)
dta <- data.frame(
"rsp" = sample(c("Y", "N"), n, TRUE),
"grp" = c(
sample(c("A", "Placebo"), round(n - 0.1 * n), TRUE),
rep("C", round(0.1 * n))
),
"f1" = sample(c("a1", "a2"), n, TRUE),
"f2" = sample(c("x", "y", "z"), n, TRUE),
stringsAsFactors = TRUE
)
lyt <- basic_table() |>
split_cols_by(var = "grp", ref_group = "Placebo") |>
analyze(
vars = "rsp",
afun = a_test_proportion_diff_mf,
extra_args = list(
val = "Y",
variables = list(strata = c("f1", "f2"))
)
)
build_table(lyt, df = dta)
test_prop_d <- s_test_proportion_diff_mf(
df = subset(dta, grp == "A"),
.var = "rsp",
.ref_group = subset(dta, grp == "Placebo"),
.in_ref_col = FALSE,
val = "Y",
variables = list(strata = c("f1", "f2"))
)
test_prop_d
Obtain the default theme for the docx
Description
This function is based on rtables.officer::theme_docx_default().
Usage
theme_docx_default_j(
font = "Times New Roman",
font_size = 9L,
cell_margins = c(0, 0, 0, 0),
bold = c("header", "content_rows", "label_rows", "top_left"),
bold_manual = NULL,
border = flextable::fp_border_default(width = 0.875, color = "black")
)
Arguments
font |
( |
font_size |
( |
cell_margins |
( |
bold |
( |
bold_manual |
( |
border |
( |
Value
A function that applies the given theme to a flextable.
Note
This function may be removed from junco in the future if the functionality
is merged into rtables.officer.
For more information, refer to the vignette table_and_listing_customizations
(browseVignettes("junco"))
Helper method (for broom::tidy()) to prepare a data frame from an
pool rbmi object containing the LS means and contrasts and multiple visits
Description
Helper method (for broom::tidy()) to prepare a data frame from an
pool rbmi object containing the LS means and contrasts and multiple visits
Usage
## S3 method for class 'pool'
tidy(x, visits, ...)
Arguments
x |
( |
visits |
( |
... |
Additional arguments. Not used. Needed to match generic signature only. |
Value
A data.frame.
Convert a TableTree or a listing_df object to a flextable
Description
This function is based on rtables.officer::tt_to_flextable().
Usage
tt_to_flextable_j(
tt,
tblid = NULL,
theme = theme_docx_default_j(font = "Times New Roman", font_size = 9L, bold = NULL),
border = flextable::fp_border_default(width = 0.875, color = "black"),
titles_as_header = TRUE,
bold_titles = TRUE,
integrate_footers = TRUE,
counts_in_newline = FALSE,
paginate = tlg_type(tt) == "Table",
fontspec = formatters::font_spec("Times", 9L, 1.2),
colwidths = NULL,
label_width_ins = 2,
total_page_width = pg_width_by_orient(orientation == "landscape"),
orientation = "portrait",
nosplitin = list(row = character(), col = character()),
string_map = default_str_map,
markup_df_docx = dps_markup_df_docx,
reduce_first_col_indentation = FALSE,
tlgtype = tlg_type(tt),
col_gap = ifelse(tlgtype == "Listing", 0.5, 3),
round_type = formatters::obj_round_type(tt),
alignments = list(),
border_mat = make_header_bordmat(obj = tt),
validate = TRUE,
...
)
Arguments
tt |
( |
tblid |
( |
theme |
(function factory) |
border |
( |
titles_as_header |
( |
bold_titles |
( |
integrate_footers |
( |
counts_in_newline |
( |
paginate |
( |
fontspec |
( |
colwidths |
( |
label_width_ins |
( |
total_page_width |
( |
orientation |
( |
nosplitin |
( |
string_map |
( |
markup_df_docx |
( |
reduce_first_col_indentation |
( |
tlgtype |
( |
col_gap |
( |
round_type |
( |
alignments |
( |
border_mat |
( |
validate |
( |
... |
other parameters. |
Value
a flextable object.
Note
This function may be removed from junco in the future if the functionality
is merged into rtables.officer.
For more information, refer to the vignette table_and_listing_customizations
(browseVignettes("junco"))
Note
The following features are not implemented in flextable,
and as a result they will only be visible when exporting to docx using
export_TLG_as_docx():
watermark
hanging indents
caption style
page numbering
Create TableTree as DataFrame via gentlg
Description
Create TableTree as DataFrame via gentlg
Usage
tt_to_tbldf(
tt,
fontspec = font_spec("Times", 9L, 1),
string_map = default_str_map,
markup_df = dps_markup_df,
round_type = obj_round_type(tt),
validate = TRUE
)
Arguments
tt |
( |
fontspec |
( |
string_map |
( |
markup_df |
( |
round_type |
( |
validate |
logical(1). Whether to validate the table structure using
|
Value
tt represented as a tbl data.frame suitable for passing
to tidytlg::gentlg via the huxme argument.
TableTree to .rtf Conversion
Description
A function to convert TableTree to .rtf
Usage
tt_to_tlgrtf(
tt,
file = NULL,
orientation = c("portrait", "landscape"),
colwidths = def_colwidths(tt, fontspec, col_gap = col_gap, label_width_ins =
label_width_ins, type = tlgtype),
label_width_ins = 2,
watermark = NULL,
pagenum = ifelse(tlgtype == "Listing", TRUE, FALSE),
fontspec = font_spec("Times", 9L, 1.2),
pg_width = pg_width_by_orient(orientation == "landscape"),
margins = c(0, 0, 0, 0),
paginate = tlg_type(tt) == "Table",
col_gap = ifelse(tlgtype == "Listing", 0.5, 3),
nosplitin = list(row = character(), col = character()),
verbose = FALSE,
tlgtype = tlg_type(tt),
string_map = default_str_map,
markup_df = dps_markup_df,
combined_rtf = FALSE,
one_table = TRUE,
border_mat = make_header_bordmat(obj = tt),
round_type = obj_round_type(tt),
alignments = list(),
validate = TRUE,
export_csv = FALSE,
output_csv_directory = NULL,
...
)
Arguments
tt |
( |
file |
( |
orientation |
( |
colwidths |
( |
label_width_ins |
( |
watermark |
(optional) String containing the desired watermark for RTF outputs. Vectorized. |
pagenum |
( |
fontspec |
( |
pg_width |
( |
margins |
( |
paginate |
( |
col_gap |
( |
nosplitin |
( |
verbose |
( |
tlgtype |
( |
string_map |
( |
markup_df |
( |
combined_rtf |
( |
one_table |
( |
border_mat |
( |
round_type |
( |
alignments |
( |
validate |
( |
export_csv |
( |
output_csv_directory |
( |
... |
Additional arguments passed to gentlg |
Details
This function aids in converting the rtables TableTree into the desired .rtf file.
Value
If file is non-NULL, this is called for the side-effect of writing
one or more RTF files. Otherwise, returns a list of huxtable objects.
Note
file should always include path. Path will be extracted
and passed separately to gentlg.
When one_table is FALSE, only the width of the row label
pseudocolumn can be directly controlled due to a limitation in
tidytlg::gentlg. The proportion of the full page that the first value
in colwidths would take up is preserved and all other columns equally
split the remaining available width. This will cause, e.g., the
elements within the allparts rtf generated when combined_rtf is TRUE
to differ visually from the content of the individual part rtfs.
Relabel Variables in a Dataset
Description
This function relabels variables in a dataset based on a provided list of labels. It can either replace existing labels or only add labels to variables without them.
Usage
var_relabel_list(x, lbl_list, replace_existing = TRUE)
Arguments
x |
( |
lbl_list |
( |
replace_existing |
( |
Value
The dataset with updated variable labels.