
Pairwise comparisons of each experimental arm against a shared control
Source:R/pairwise_fast.R
pairwise_fast.RdRuns the two-group analysis of analysis_fast once for each
experimental arm against a common control arm, on multi-arm simulated data
such as the output of simdata_fast with a length-greater-than-two
n. The contrasts are analyzed at a shared set of looks, and the results
are stacked into one long data frame with an arm column, optionally with
a Bonferroni-adjusted p-value across the contrasts.
Usage
pairwise_fast(
data,
control,
event.looks = NULL,
time.looks = NULL,
primary = NULL,
arms = NULL,
stat = "logrank",
adjust = c("none", "bonferroni"),
p.col = NULL,
cutoff.looks = NULL,
...
)Arguments
- data
A data frame of simulated trial data with columns
sim,group,accrual_time,tte, andevent, as produced bysimdata_fast.- control
The group label of the control arm.
- event.looks
A numeric vector of target cumulative event counts for the primary contrast, one per look. Mutually exclusive with
time.looksandcutoff.looks; requiresprimary.- time.looks
A numeric vector of calendar times, one per look. Mutually exclusive with
event.looksandcutoff.looks.- primary
The group label of the experimental arm whose control-versus-arm comparison defines the shared calendar cutoff. Required with
event.looksand ignored withtime.looksandcutoff.looks.- arms
A vector of experimental arm labels to compare against the control. Defaults to every group other than
control.- stat
The test statistic passed to
analysis_fast(for example"logrank","coxph", or"rmst").- adjust
Multiplicity adjustment across contrasts. Either
"none"(default) or"bonferroni", which adds ap.adjcolumn.- p.col
The name of the p-value column to adjust. By default it is the column matching the chosen
stat(for example"logrank.p").- cutoff.looks
A numeric matrix of per-simulation calendar cutoffs with one row per simulated trial and one column per look, as returned by
cutoff_fast. Mutually exclusive withevent.looksandtime.looks. Seeanalysis_fastfor how the rows are matched to the simulations.- ...
Further arguments passed to
analysis_fast, such asside,conf.level,tau,rho, andgamma. The argumentby.subgroupis not supported.
Value
A data frame with one row per contrast, look, and simulation. The
first column is arm (the experimental arm compared against
control), followed by the columns returned by
analysis_fast: sim, look, look.value,
cutoff, reached, the enrollment and event counts, and the
statistic columns for the chosen stat. When adjust =
"bonferroni" a p.adj column is appended.
Details
Three timing regimes are supported, exactly one of which must be requested.
With time.looks, every contrast is analyzed at the same fixed calendar
time or times, so all contrasts share the same data cutoff by construction.
With event.looks, the analysis is event-driven and primary names
the experimental arm whose control-versus-arm comparison defines the data
cutoff. The primary contrast is analyzed at the requested cumulative event
counts, its per-simulation calendar cutoffs are recorded, and then every
contrast, including the primary one, is analyzed at those same cutoffs. This
reproduces the standard design in which the primary event-driven analysis
fixes a single data cutoff at which all comparisons are performed. For a
simulation in which the primary event target is not reached at a look, that
look is marked with reached = FALSE, and its counts and statistics are
NA for every contrast. The shared cutoffs are computed by cutoff_fast on the
events of the control and primary arms.
With cutoff.looks, every contrast is analyzed at the supplied
per-simulation calendar cutoffs, for example those returned by
cutoff_fast for a combination of event and calendar-time rules.
A look that is not reached in a simulation (NA cutoff) is marked with
reached = FALSE and NA counts and statistics, as in the
event-driven regime. This differs from analysis_fast, which
analyzes the full data at an unreached look; in
simsummary_fast an unreached look of pairwise_fast
output therefore never crosses a boundary.
The Bonferroni option multiplies each p-value by the number of contrasts and
caps it at one, controlling the family-wise error rate across the
control-versus-arm comparisons at each look. Multiplicity across looks is a
separate matter handled by group-sequential boundaries in
simsummary_fast, not by this adjustment; given the output of
this function, simsummary_fast summarizes each arm separately (the
Bonferroni-adjusted p-values can be used there through
p.col = "p.adj").
This is a single-endpoint helper: it reads the tte and event
columns and does not support subgroups. Comparisons for a second endpoint are
obtained by calling pairwise_fast again on that endpoint's columns.
Examples
# Three-arm trial: control (group 1) and two experimental arms.
dfk <- simdata_fast(
nsim = 100,
n = c(120, 120, 120),
a.time = c(0, 12),
a.rate = 360 / 12,
e.median = list(12, 16, 20),
seed = 8
)
# Fixed calendar look at month 30, Bonferroni across the two contrasts.
pw <- pairwise_fast(dfk, control = 1, time.looks = 30,
stat = "logrank", side = 1, adjust = "bonferroni")
head(pw)
#> arm sim look look.value cutoff reached n.enrolled n.event n.dropout
#> 1 2 1 1 30 30 TRUE 240 173 0
#> 2 2 2 1 30 30 TRUE 240 160 0
#> 3 2 3 1 30 30 TRUE 240 176 0
#> 4 2 4 1 30 30 TRUE 240 176 0
#> 5 2 5 1 30 30 TRUE 240 168 0
#> 6 2 6 1 30 30 TRUE 240 160 0
#> n.pipeline logrank.z logrank.chisq logrank.p p.adj
#> 1 67 -2.0654860 4.26623257 0.01943852 0.03887704
#> 2 80 -2.1030267 4.42272144 0.01773172 0.03546343
#> 3 64 -0.6031565 0.36379774 0.27320230 0.54640460
#> 4 64 -2.1304840 4.53896204 0.01656584 0.03313168
#> 5 72 0.1039376 0.01080303 0.54139057 1.00000000
#> 6 80 -2.0645649 4.26242820 0.01948209 0.03896419
# Event-driven: arm 3 is the primary contrast and its 200th control-plus-arm-3
# event fixes the cutoff at which both contrasts are analyzed.
pw2 <- pairwise_fast(dfk, control = 1, event.looks = 200, primary = 3,
stat = "logrank", side = 1, adjust = "bonferroni")
head(pw2)
#> arm sim look look.value cutoff reached n.enrolled n.event n.dropout
#> 1 2 1 1 200 45.50440 TRUE 240 210 0
#> 2 2 2 1 200 47.69751 TRUE 240 208 0
#> 3 2 3 1 200 45.98303 TRUE 240 210 0
#> 4 2 4 1 200 44.93080 TRUE 240 210 0
#> 5 2 5 1 200 43.31435 TRUE 240 209 0
#> 6 2 6 1 200 55.37777 TRUE 240 220 0
#> n.pipeline logrank.z logrank.chisq logrank.p p.adj
#> 1 30 -1.6385354 2.6847984 0.05065502 0.10131005
#> 2 32 -2.5714433 6.6123205 0.00506378 0.01012756
#> 3 30 -1.1258351 1.2675046 0.13011767 0.26023534
#> 4 30 -1.7611765 3.1017428 0.03910426 0.07820853
#> 5 31 -0.3822314 0.1461008 0.35114487 0.70228974
#> 6 20 -1.3978726 1.9540478 0.08107566 0.16215132