gs_power_npe.Rd
gs_power_npe()
derives group sequential bounds and boundary crossing probabilities for a design.
It allows a non-constant treatment effect over time, but also can be applied for the usual homogeneous effect size designs.
It requires treatment effect and statistical information at each analysis as well as a method of deriving bounds, such as spending.
The routine enables two things not available in the gsDesign package: 1) non-constant effect, 2) more flexibility in boundary selection.
For many applications, the non-proportional-hazards design function gs_design_nph()
will be used; it calls this function.
Initial bound types supported are 1) spending bounds, 2) fixed bounds, and 3) Haybittle-Peto-like bounds.
The requirement is to have a boundary update method that can each bound without knowledge of future bounds.
As an example, bounds based on conditional power that require knowledge of all future bounds are not supported by this routine;
a more limited conditional power method will be demonstrated.
Boundary family designs Wang-Tsiatis designs including the original (non-spending-function-based) O'Brien-Fleming and Pocock designs
are not supported by gs_power_npe()
.
gs_power_npe( theta = 0.1, theta1 = NULL, info = 1, info1 = NULL, info0 = NULL, binding = FALSE, upper = gs_b, lower = gs_b, upar = qnorm(0.975), lpar = -Inf, test_upper = TRUE, test_lower = TRUE, r = 18, tol = 1e-06 )
theta | natural parameter for group sequential design representing expected incremental drift at all analyses; used for power calculation |
---|---|
theta1 | natural parameter for alternate hypothesis, if needed for lower bound computation |
info | statistical information at all analyses for input |
info1 | statistical information under hypothesis used for futility bound calculation if different from
|
info0 | statistical information under null hypothesis, if different than |
binding | indicator of whether futility bound is binding; default of FALSE is recommended |
upper | function to compute upper bound |
lower | function to compare lower bound |
upar | parameter to pass to upper |
lpar | parameter to pass to lower |
test_upper | indicator of which analyses should include an upper (efficacy) bound;
single value of TRUE (default) indicates all analyses; otherwise,
a logical vector of the same length as |
test_lower | indicator of which analyses should include a lower bound;
single value of TRUE (default) indicates all analyses;
single value FALSE indicated no lower bound; otherwise,
a logical vector of the same length as |
r | Integer, at least 2; default of 18 recommended by Jennison and Turnbull |
tol | Tolerance parameter for boundary convergence (on Z-scale) |
Keaven Anderson keaven\_anderson@merck.
library(gsDesign) # Default (single analysis; Type I error controlled) gs_power_npe(theta=0) %>% filter(Bound=="Upper")#> # A tibble: 1 x 9 #> Analysis Bound Z Probability theta theta1 info info0 info1 #> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 Upper 1.96 0.0250 0 0 1 1 1# Fixed bound gs_power_npe(theta = c(.1, .2, .3), info = (1:3) * 40, info0 = (1:3) * 40, upper = gs_b, upar = gsDesign::gsDesign(k=3,sfu=gsDesign::sfLDOF)$upper$bound, lower = gs_b, lpar = c(-1, 0, 0))#> # A tibble: 6 x 9 #> Analysis Bound Z Probability theta theta1 info info0 info1 #> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 Upper 3.71 0.00104 0.1 0.1 40 40 40 #> 2 2 Upper 2.51 0.235 0.2 0.2 80 80 80 #> 3 3 Upper 1.99 0.869 0.3 0.3 120 120 120 #> 4 1 Lower -1 0.0513 0.1 0.1 40 40 40 #> 5 2 Lower 0 0.0715 0.2 0.2 80 80 80 #> 6 3 Lower 0 0.0715 0.3 0.3 120 120 120# Same fixed efficacy bounds, no futility bound (i.e., non-binding bound), null hypothesis gs_power_npe(theta = rep(0,3), info = (1:3) * 40, upar = gsDesign::gsDesign(k=3,sfu=gsDesign::sfLDOF)$upper$bound, lpar = rep(-Inf, 3)) %>% filter(Bound=="Upper")#> # A tibble: 3 x 9 #> Analysis Bound Z Probability theta theta1 info info0 info1 #> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 Upper 3.71 0.000104 0 0 40 40 40 #> 2 2 Upper 2.51 0.00605 0 0 80 80 80 #> 3 3 Upper 1.99 0.0250 0 0 120 120 120# Fixed bound with futility only at analysis 1; efficacy only at analyses 2, 3 gs_power_npe(theta = c(.1, .2, .3), info = (1:3) * 40, upar = c(Inf, 3, 2), lpar = c(qnorm(.1), -Inf, -Inf))#> # A tibble: 6 x 9 #> Analysis Bound Z Probability theta theta1 info info0 info1 #> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 Upper Inf 0 0.1 0.1 40 40 40 #> 2 2 Upper 3 0.113 0.2 0.2 80 80 80 #> 3 3 Upper 2 0.887 0.3 0.3 120 120 120 #> 4 1 Lower -1.28 0.0278 0.1 0.1 40 40 40 #> 5 2 Lower -Inf 0.0278 0.2 0.2 80 80 80 #> 6 3 Lower -Inf 0.0278 0.3 0.3 120 120 120# Spending function bounds # Lower spending based on non-zero effect gs_power_npe(theta = c(.1, .2, .3), info = (1:3) * 40, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL))#> # A tibble: 6 x 9 #> Analysis Bound Z Probability theta theta1 info info0 info1 #> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 Upper 3.71 0.00104 0.1 0.1 40 40 40 #> 2 2 Upper 2.51 0.235 0.2 0.2 80 80 80 #> 3 3 Upper 1.99 0.883 0.3 0.3 120 120 120 #> 4 1 Lower -1.36 0.0230 0.1 0.1 40 40 40 #> 5 2 Lower 0.0726 0.0552 0.2 0.2 80 80 80 #> 6 3 Lower 1.86 0.100 0.3 0.3 120 120 120# Same bounds, but power under different theta gs_power_npe(theta = c(.15, .25, .35), theta1 = c(.1, .2, .3), info = (1:3) * 40, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL))#> # A tibble: 6 x 9 #> Analysis Bound Z Probability theta theta1 info info0 info1 #> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 Upper 3.71 0.00288 0.15 0.1 40 40 40 #> 2 2 Upper 2.51 0.392 0.25 0.2 80 80 80 #> 3 3 Upper 1.99 0.956 0.35 0.3 120 120 120 #> 4 1 Lower -1.36 0.0104 0.15 0.1 40 40 40 #> 5 2 Lower 0.0726 0.0221 0.25 0.2 80 80 80 #> 6 3 Lower 1.86 0.0370 0.35 0.3 120 120 120# Two-sided symmetric spend, O'Brien-Fleming spending # Typically, 2-sided bounds are binding xx <- gs_power_npe(theta = rep(0, 3), theta1 = rep(0, 3), info = (1:3) * 40, upper = gs_spending_bound, binding = TRUE, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL)) xx#> # A tibble: 6 x 9 #> Analysis Bound Z Probability theta theta1 info info0 info1 #> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 Upper 3.71 0.000104 0 0 40 40 40 #> 2 2 Upper 2.51 0.00605 0 0 80 80 80 #> 3 3 Upper 1.99 0.0250 0 0 120 120 120 #> 4 1 Lower -3.71 0.000104 0 0 40 40 40 #> 5 2 Lower -2.51 0.00605 0 0 80 80 80 #> 6 3 Lower -1.99 0.0250 0 0 120 120 120# Re-use these bounds under alternate hypothesis # Always use binding = TRUE for power calculations upar <- (xx %>% filter(Bound=="Upper"))$Z gs_power_npe(theta = c(.1, .2, .3), info = (1:3) * 40, binding = TRUE, upar = upar, lpar = -upar)#> # A tibble: 6 x 9 #> Analysis Bound Z Probability theta theta1 info info0 info1 #> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 Upper 3.71 0.00104 0.1 0.1 40 40 40 #> 2 2 Upper 2.51 0.235 0.2 0.2 80 80 80 #> 3 3 Upper 1.99 0.902 0.3 0.3 120 120 120 #> 4 1 Lower -3.71 0.00000704 0.1 0.1 40 40 40 #> 5 2 Lower -2.51 0.0000151 0.2 0.2 80 80 80 #> 6 3 Lower -1.99 0.0000151 0.3 0.3 120 120 120