Skip to content

Commit 549dc46

Browse files
authored
Merge pull request #510 from Merck/494-develop-gs_cp_npe-with-theta-and-info-as-input
Add a new function `gs_cp_npe`
2 parents 4aafff4 + 809ed32 commit 549dc46

File tree

5 files changed

+139
-2
lines changed

5 files changed

+139
-2
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export(fixed_design_milestone)
2727
export(fixed_design_rd)
2828
export(fixed_design_rmst)
2929
export(gs_b)
30+
export(gs_cp_npe)
3031
export(gs_create_arm)
3132
export(gs_design_ahr)
3233
export(gs_design_combo)

R/gs_cp_npe.R

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright (c) 2024 Merck & Co., Inc., Rahway, NJ, USA and its affiliates.
2+
# All rights reserved.
3+
#
4+
# This file is part of the gsDesign2 program.
5+
#
6+
# gsDesign2 is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
19+
#' Conditional power computation with non-constant effect size
20+
#'
21+
#' @details
22+
#' We assume \eqn{Z_1} and \eqn{Z_2} are the z-values at an interim analysis and later analysis, respectively.
23+
#' We assume further \eqn{Z_1} and \eqn{Z_2} are bivariate normal with standard group sequential assumptions
24+
#' on independent increments where for \eqn{i=1,2}
25+
#' \deqn{E(Z_i) = \theta_i\sqrt{I_i}}
26+
#' \deqn{Var(Z_i) = 1/I_i}
27+
#' \deqn{Cov(Z_1, Z_2) = t \equiv I_1/I_2}
28+
#' where \eqn{\theta_1, \theta_2} are real values and \eqn{0<I_1<I_2}.
29+
#' See https://merck.github.io/gsDesign2/articles/story-npe-background.html for assumption details.
30+
#' Returned value is
31+
#' \deqn{P(Z_2 > b \mid Z_1 = a) = 1 - \Phi\left(\frac{b - \sqrt{t}a - \sqrt{I_2}(\theta_2 - \theta_1\sqrt{t})}{\sqrt{1 - t}}\right)}
32+
#'
33+
#' @param theta A vector of length two, which specifies the natural parameter for treatment effect.
34+
#' The first element of `theta` is the treatment effect of an interim analysis i.
35+
#' The second element of `theta` is the treatment effect of a future analysis j.
36+
#' @param info A vector of two, which specifies the statistical information under the treatment effect `theta`.
37+
#' @param a Interim z-value at analysis i (scalar).
38+
#' @param b Future target z-value at analysis j (scalar).
39+
#' @return A scalar with the conditional power \eqn{P(Z_2>b\mid Z_1=a)}.
40+
#' @export
41+
#'
42+
#' @examples
43+
#' library(gsDesign2)
44+
#' library(dplyr)
45+
#'
46+
#' # Calculate conditional power under arbitrary theta and info
47+
#' # In practice, the value of theta and info commonly comes from a design.
48+
#' # More examples are available at the pkgdown vignettes.
49+
#' gs_cp_npe(theta = c(.1, .2),
50+
#' info = c(15, 35),
51+
#' a = 1.5, b = 1.96)
52+
gs_cp_npe <- function(theta = NULL,
53+
info = NULL,
54+
a = NULL, b = NULL
55+
) {
56+
# ----------------------------------------- #
57+
# input checking #
58+
# ----------------------------------------- #
59+
# check theta
60+
if (is.null(theta)) {
61+
stop("Please provide theta (arbitrary treatment effect) to calculate conditional power.")
62+
} else if (length(theta) == 1) {
63+
theta <- rep(theta, 2)
64+
}
65+
66+
# check info
67+
if (is.null(info)) {
68+
stop("Please provide info (statistical information given the treatment effect theta) to calculate conditional power.")
69+
}
70+
71+
check_info(info)
72+
73+
# ----------------------------------------- #
74+
# calculate conditional power under theta #
75+
# ----------------------------------------- #
76+
t <- info[2] / info[1]
77+
numerator1 <- b - a * sqrt(t)
78+
numerator2 <- theta[2] * sqrt(info[2]) - theta[1] * sqrt(t * info[1])
79+
denominator <- sqrt(1 - t)
80+
conditional_power <- pnorm((numerator1 - numerator2) / denominator, lower.tail = FALSE)
81+
82+
return(conditional_power)
83+
}

_pkgdown.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ reference:
7373
- gs_info_rd
7474
- gs_power_rd
7575
- gs_design_rd
76+
- title: "Conditional power"
77+
desc: >
78+
Functions for conditional power.
79+
contents:
80+
- gs_cp_npe
7681
- title: "Input definition"
7782
desc: >
7883
Helper functions to define inputs for study design.

man/gs_cp_npe.Rd

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

vignettes/articles/story-npe-background.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ mt <- tibble::tribble(
112112
"$1$",
113113
"$B_k=\\sqrt{t_k}Z_k$", "$\\sum_{i=1}^{n_k}X_i/\\sqrt N$",
114114
"$t_k\\sqrt{\\mathcal{I}_K}\\
115-
\theta(t_k)=\\mathcal{I}_k\\
116-
\theta(t_k)/\\sqrt{\\mathcal{I}_K}$",
115+
\\theta(t_k)=\\mathcal{I}_k\\
116+
\\theta(t_k)/\\sqrt{\\mathcal{I}_K}$",
117117
"$t_k$"
118118
)
119119
mt %>% kable(escape = FALSE)

0 commit comments

Comments
 (0)