|
| 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 | +} |
0 commit comments