Skip to content

Commit 325f54a

Browse files
Merge pull request #567 from Merck/520-improve-the-help-file-of-gs_power_npe-and-gs_design_npe
Improve the help file of `gs_power_npe` and `gs_design_npe`
2 parents ef2e188 + c180105 commit 325f54a

File tree

5 files changed

+532
-650
lines changed

5 files changed

+532
-650
lines changed

R/gs_design_npe.R

Lines changed: 13 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -16,83 +16,14 @@
1616
# You should have received a copy of the GNU General Public License
1717
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1818

19-
#' Group sequential design computation with non-constant effect and information
20-
#'
21-
#' Derives group sequential design size,
22-
#' bounds and boundary crossing probabilities based on proportionate
23-
#' information and effect size at analyses.
24-
#' It allows a non-constant treatment effect over time,
25-
#' but also can be applied for the usual homogeneous effect size designs.
26-
#' It requires treatment effect and proportionate statistical information
27-
#' at each analysis as well as a method of deriving bounds, such as spending.
28-
#' The routine enables two things not available in the gsDesign package:
29-
#' 1) non-constant effect, 2) more flexibility in boundary selection.
30-
#' For many applications, the non-proportional-hazards design function
31-
#' `gs_design_nph()` will be used; it calls this function.
32-
#' Initial bound types supported are 1) spending bounds,
33-
#' 2) fixed bounds, and 3) Haybittle-Peto-like bounds.
34-
#' The requirement is to have a boundary update method that
35-
#' can each bound without knowledge of future bounds.
36-
#' As an example, bounds based on conditional power that
37-
#' require knowledge of all future bounds are not supported by this routine;
38-
#' a more limited conditional power method will be demonstrated.
39-
#' Boundary family designs Wang-Tsiatis designs including
40-
#' the original (non-spending-function-based) O'Brien-Fleming and Pocock designs
41-
#' are not supported by [gs_power_npe()].
42-
#'
43-
#' @param theta Natural parameter for group sequential design
44-
#' representing expected incremental drift at all analyses;
45-
#' used for power calculation.
46-
#' @param theta0 Natural parameter used for upper bound spending;
47-
#' if `NULL`, this will be set to 0.
48-
#' @param theta1 Natural parameter used for lower bound spending;
49-
#' if `NULL`, this will be set to `theta`
50-
#' which yields the usual beta-spending.
51-
#' If set to 0, spending is 2-sided under null hypothesis.
52-
#' @param info Proportionate statistical information at
53-
#' all analyses for input `theta`.
54-
#' @param info0 Proportionate statistical information
55-
#' under null hypothesis, if different than alternative;
56-
#' impacts null hypothesis bound calculation.
57-
#' @param info1 Proportionate statistical information
58-
#' under alternate hypothesis;
59-
#' impacts null hypothesis bound calculation.
60-
#' @param info_scale Information scale for calculation. Options are:
61-
#' - `"h0_h1_info"` (default): variance under both null and alternative hypotheses is used.
62-
#' - `"h0_info"`: variance under null hypothesis is used.
63-
#' - `"h1_info"`: variance under alternative hypothesis is used.
19+
#' @rdname gs_power_design_npe
6420
#' @param alpha One-sided Type I error.
6521
#' @param beta Type II error.
66-
#' @param binding Indicator of whether futility bound is binding;
67-
#' default of `FALSE` is recommended.
68-
#' @param upper Function to compute upper bound.
69-
#' @param lower Function to compare lower bound.
70-
#' @param upar Parameters passed to the function provided in `upper`.
71-
#' @param lpar Parameters passed to the function provided in `lower`.
72-
#' @param test_upper Indicator of which analyses should include
73-
#' an upper (efficacy) bound; single value of `TRUE` (default) indicates
74-
#' all analyses; otherwise, a logical vector of the same length as `info`
75-
#' should indicate which analyses will have an efficacy bound.
76-
#' @param test_lower Indicator of which analyses should include an lower bound;
77-
#' single value of `TRUE` (default) indicates all analyses;
78-
#' single value `FALSE` indicates no lower bound; otherwise,
79-
#' a logical vector of the same length as `info` should indicate which
80-
#' analyses will have a lower bound.
81-
#' @param r Integer value controlling grid for numerical integration
82-
#' as in Jennison and Turnbull (2000); default is 18, range is 1 to 80.
83-
#' Larger values provide larger number of grid points and greater accuracy.
84-
#' Normally `r` will not be changed by the user.
85-
#' @param tol Tolerance parameter for boundary convergence (on Z-scale).
86-
#'
87-
#' @return A tibble with columns analysis, bound, z, probability, theta, info, info0.
88-
#'
22+
8923
#' @details
90-
#' The inputs `info` and `info0` should be
91-
#' vectors of the same length with increasing positive numbers.
92-
#' The design returned will change these by some constant scale
93-
#' factor to ensure the design has power `1 - beta`.
94-
#' The bound specifications in `upper`, `lower`, `upar`, `lpar`
24+
#' The bound specifications (`upper`, `lower`, `upar`, `lpar`) of \code{gs_design_npe()}
9525
#' will be used to ensure Type I error and other boundary properties are as specified.
26+
#' See the help file of \code{gs_spending_bound()} for details on spending function.
9627
#'
9728
#' @section Specification:
9829
#' \if{latex}{
@@ -127,11 +58,10 @@
12758
#' @export
12859
#'
12960
#' @examples
130-
#' library(dplyr)
13161
#' library(gsDesign)
13262
#'
13363
#' # Example 1 ----
134-
#' # Single analysis
64+
#' # gs_design_npe with single analysis
13565
#' # Lachin book p 71 difference of proportions example
13666
#' pc <- .28 # Control response rate
13767
#' pe <- .40 # Experimental response rate
@@ -147,7 +77,7 @@
14777
#'
14878
#'
14979
#' # Example 2 ----
150-
#' # Fixed bound
80+
#' # gs_design_npe with with fixed bound
15181
#' x <- gs_design_npe(
15282
#' alpha = 0.0125,
15383
#' theta = c(.1, .2, .3),
@@ -163,15 +93,15 @@
16393
#' # Same upper bound; this represents non-binding Type I error and will total 0.025
16494
#' gs_power_npe(
16595
#' theta = rep(0, 3),
166-
#' info = (x |> filter(bound == "upper"))$info,
96+
#' info = (x |> dplyr::filter(bound == "upper"))$info,
16797
#' upper = gs_b,
168-
#' upar = (x |> filter(bound == "upper"))$z,
98+
#' upar = (x |> dplyr::filter(bound == "upper"))$z,
16999
#' lower = gs_b,
170100
#' lpar = rep(-Inf, 3)
171101
#' )
172102
#'
173103
#' # Example 3 ----
174-
#' # Spending bound examples
104+
#' # gs_design_npe with spending bound
175105
#' # Design with futility only at analysis 1; efficacy only at analyses 2, 3
176106
#' # Spending bound for efficacy; fixed bound for futility
177107
#' # NOTE: test_upper and test_lower DO NOT WORK with gs_b; must explicitly make bounds infinite
@@ -201,7 +131,7 @@
201131
#' )
202132
#'
203133
#' # Example 4 ----
204-
#' # Spending function bounds
134+
#' # gs_design_npe with spending function bounds
205135
#' # 2-sided asymmetric bounds
206136
#' # Lower spending based on non-zero effect
207137
#' gs_design_npe(
@@ -215,7 +145,7 @@
215145
#' )
216146
#'
217147
#' # Example 5 ----
218-
#' # Two-sided symmetric spend, O'Brien-Fleming spending
148+
#' # gs_design_npe with two-sided symmetric spend, O'Brien-Fleming spending
219149
#' # Typically, 2-sided bounds are binding
220150
#' xx <- gs_design_npe(
221151
#' theta = c(.1, .2, .3),
@@ -236,8 +166,8 @@
236166
#' binding = TRUE,
237167
#' upper = gs_b,
238168
#' lower = gs_b,
239-
#' upar = (xx |> filter(bound == "upper"))$z,
240-
#' lpar = -(xx |> filter(bound == "upper"))$z
169+
#' upar = (xx |> dplyr::filter(bound == "upper"))$z,
170+
#' lpar = -(xx |> dplyr::filter(bound == "upper"))$z
241171
#' )
242172
gs_design_npe <- function(
243173
theta = .1, theta0 = 0, theta1 = theta, # 3 theta

R/gs_power_npe.R

Lines changed: 69 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,44 +16,55 @@
1616
# You should have received a copy of the GNU General Public License
1717
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1818

19-
#' Group sequential bound computation with non-constant effect
19+
#' @title Group sequential design computation with non-constant effect and information.
2020
#'
21-
#' Derives group sequential bounds and boundary crossing probabilities for a design.
22-
#' It allows a non-constant treatment effect over time,
21+
#' @description The following two functions allow a non-constant treatment effect over time,
2322
#' but also can be applied for the usual homogeneous effect size designs.
24-
#' It requires treatment effect and statistical information at each analysis
23+
#' They require treatment effect and statistical information at each analysis
2524
#' as well as a method of deriving bounds, such as spending.
26-
#' The routine enables two things not available in the gsDesign package:
27-
#' 1) non-constant effect, 2) more flexibility in boundary selection.
28-
#' For many applications, the non-proportional-hazards design function
29-
#' `gs_design_nph()` will be used; it calls this function.
30-
#' Initial bound types supported are 1) spending bounds,
31-
#' 2) fixed bounds, and 3) Haybittle-Peto-like bounds.
32-
#' The requirement is to have a boundary update method that can
33-
#' each bound without knowledge of future bounds.
34-
#' As an example, bounds based on conditional power that require
35-
#' knowledge of all future bounds are not supported by this routine;
36-
#' a more limited conditional power method will be demonstrated.
37-
#' Boundary family designs Wang-Tsiatis designs including the
38-
#' original (non-spending-function-based) O'Brien-Fleming and Pocock designs
39-
#' are not supported by `gs_power_npe()`.
25+
#' Initial bound types supported are spending bounds and fixed bounds.
26+
#' These routines enables two things not available in the gsDesign package: 1)
27+
#' non-constant effect, 2) more flexibility in boundary selection.
28+
#'
29+
#' \code{gs_power_npe()} derives group sequential bounds and boundary crossing probabilities
30+
#' for a design, given treatment effect and information at each analysis and the
31+
#' method of deriving bounds, such as spending.
32+
#'
33+
#' \code{gs_design_npe()} derives group sequential design size,
34+
#' bounds and boundary crossing probabilities based on proportionate
35+
#' information and effect size at analyses, as well as the
36+
#' method of deriving bounds, such as spending.
37+
#'
38+
#' The only differences in arguments between the two functions are the \code{alpha} and \code{beta}
39+
#' parameters used in the \code{gs_design_npe()}.
4040
#'
4141
#' @param theta Natural parameter for group sequential design representing
42-
#' expected incremental drift at all analyses; used for power calculation.
43-
#' @param theta0 Natural parameter for null hypothesis,
44-
#' if needed for upper bound computation.
42+
#' expected cumulative drift at all analyses; used for power calculation.
43+
#' It can be a scalar (constant treatment effect) or a vector (non-constant treatment effect).
44+
#' The user must provide a value for `theta`.
45+
#' @param theta0 Natural parameter for null hypothesis.
46+
#' It can be a scalar (constant treatment effect) or a vector (non-constant treatment effect).
47+
#' The default is 0. If a value other than 0 is provided, it affects upper bound computation.
4548
#' @param theta1 Natural parameter for alternate hypothesis,
4649
#' if needed for lower bound computation.
50+
#' It can be a scalar (constant treatment effect) or a vector (non-constant treatment effect).
51+
#' The default is the same as `theta`, which yields the usual beta-spending.
52+
#' If set to 0, spending is 2-sided under the null hypothesis.
4753
#' @param info Statistical information at all analyses for input `theta`.
48-
#' @param info0 Statistical information under null hypothesis,
49-
#' if different than `info`;
50-
#' impacts null hypothesis bound calculation.
51-
#' @param info1 Statistical information under hypothesis used for
52-
#' futility bound calculation if different from
53-
#' `info`; impacts futility hypothesis bound calculation.
54+
#' It is a vector of positive numbers in increasing order.
55+
#' The user must provide values corresponding to `theta`.
56+
#' @param info0 Statistical information under null hypothesis.
57+
#' It is a vector of all positive numbers with increasing order.
58+
#' Default is set to be the same as `info`.
59+
#' If `info0` is different than `info`, it impacts null hypothesis bound calculation.
60+
#' @param info1 Statistical information under hypothesis used for futility bound calculation.
61+
#' It is a vector of all positive numbers with increasing order.
62+
#' Default is set to be the same as `info`.
63+
#' If `info1` is different from `info`, it impacts futility bound calculation.
5464
#' @param info_scale Information scale for calculation. Options are:
5565
#' - `"h0_h1_info"` (default): variance under both null and alternative hypotheses is used.
5666
#' - `"h0_info"`: variance under null hypothesis is used.
67+
#' This is often used for testing methods that use local alternatives, such as the Schoenfeld method.
5768
#' - `"h1_info"`: variance under alternative hypothesis is used.
5869
#' @param binding Indicator of whether futility bound is binding;
5970
#' default of `FALSE` is recommended.
@@ -77,10 +88,20 @@
7788
#' Normally, `r` will not be changed by the user.
7889
#' @param tol Tolerance parameter for boundary convergence (on Z-scale).
7990
#'
80-
#' @return A tibble with columns as analysis index, bounds, z,
81-
#' crossing probability, theta (standardized treatment effect),
82-
#' theta1 (standardized treatment effect under alternative hypothesis),
83-
#' information fraction, and statistical information.
91+
#' @return A tibble with columns of
92+
#' - `analysis`: analysis index.
93+
#' - `bound`: either of value `"upper"` or `"lower"`, indicating the upper and lower bound.
94+
#' - `z`: the Z-score bounds.
95+
#' - `probability`: cumulative probability of crossing the bound at or before the analysis.
96+
#' - `theta`: same as the input.
97+
#' - `theta1`: same as the input.
98+
#' - `info`: statistical information at each analysis.
99+
#' + If it is returned by `gs_power_npe`, the `info`, `info0`, `info1` are same as the input.
100+
#' + If it is returned by `gs_design_npe`, the `info`, `info0`, `info1` are changed by a constant scale factor.
101+
#' factor to ensure the design has power `1 - beta`.
102+
#' - `info0`: statistical information under the null at each analysis.
103+
#' - `info1`: statistical information under the alternative at each analysis.
104+
#' - `info_frac`: information fraction at each analysis, i.e., `info / max(info)`.
84105
#'
85106
#' @section Specification:
86107
#' \if{latex}{
@@ -117,17 +138,18 @@
117138
#' }
118139
#' \if{html}{The contents of this section are shown in PDF user manual only.}
119140
#'
141+
#' @name gs_power_design_npe
142+
#' @rdname gs_power_design_npe
120143
#' @export
121144
#'
122145
#' @examples
123-
#' library(dplyr)
124-
#' library(gsDesign)
125-
#' library(gsDesign2)
126146
#'
127-
#' # Default (single analysis; Type I error controlled)
128-
#' gs_power_npe(theta = 0) |> filter(bound == "upper")
147+
#' # Example 6 ----
148+
#' # Default of gs_power_npe (single analysis; Type I error controlled)
149+
#' gs_power_npe(theta = 0) |> dplyr::filter(bound == "upper")
129150
#'
130-
#' # Fixed bound
151+
#' # Example 7 ----
152+
#' # gs_power_npe with fixed bound
131153
#' gs_power_npe(
132154
#' theta = c(.1, .2, .3),
133155
#' info = (1:3) * 40,
@@ -144,9 +166,10 @@
144166
#' upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound,
145167
#' lpar = rep(-Inf, 3)
146168
#' ) |>
147-
#' filter(bound == "upper")
169+
#' dplyr::filter(bound == "upper")
148170
#'
149-
#' # Fixed bound with futility only at analysis 1; efficacy only at analyses 2, 3
171+
#' # Example 8 ----
172+
#' # gs_power_npe with fixed bound testing futility only at analysis 1; efficacy only at analyses 2, 3
150173
#' gs_power_npe(
151174
#' theta = c(.1, .2, .3),
152175
#' info = (1:3) * 40,
@@ -156,7 +179,8 @@
156179
#' lpar = c(qnorm(.1), -Inf, -Inf)
157180
#' )
158181
#'
159-
#' # Spending function bounds
182+
#' # Example 9 ----
183+
#' # gs_power_npe with spending function bounds
160184
#' # Lower spending based on non-zero effect
161185
#' gs_power_npe(
162186
#' theta = c(.1, .2, .3),
@@ -177,7 +201,8 @@
177201
#' lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL)
178202
#' )
179203
#'
180-
#' # Two-sided symmetric spend, O'Brien-Fleming spending
204+
#' # Example 10 ----
205+
#' # gs_power_npe with two-sided symmetric spend, O'Brien-Fleming spending
181206
#' # Typically, 2-sided bounds are binding
182207
#' x <- gs_power_npe(
183208
#' theta = rep(0, 3),
@@ -195,10 +220,11 @@
195220
#' theta = c(.1, .2, .3),
196221
#' info = (1:3) * 40,
197222
#' binding = TRUE,
198-
#' upar = (x |> filter(bound == "upper"))$z,
199-
#' lpar = -(x |> filter(bound == "upper"))$z
223+
#' upar = (x |> dplyr::filter(bound == "upper"))$z,
224+
#' lpar = -(x |> dplyr::filter(bound == "upper"))$z
200225
#' )
201226
#'
227+
#' # Example 11 ----
202228
#' # Different values of `r` and `tol` lead to different numerical accuracy
203229
#' # Larger `r` and smaller `tol` give better accuracy, but leads to slow computation
204230
#' n_analysis <- 5

0 commit comments

Comments
 (0)