From d4f13d0052a8f8ce2bccd3a3398bff153f4d16fc Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Sun, 26 May 2024 19:50:36 +0200 Subject: [PATCH 01/19] examples and test --- R/boundsPredprob.R | 73 +++++++++------- examples/boundsPredprob.R | 16 ++-- man/boundsPredprob.Rd | 67 ++++++++------- man/ocPredprob.Rd | 121 +++++++++++++++++++++++++++ tests/testthat/test-boundsPredprob.R | 33 ++++++++ 5 files changed, 240 insertions(+), 70 deletions(-) create mode 100644 tests/testthat/test-boundsPredprob.R diff --git a/R/boundsPredprob.R b/R/boundsPredprob.R index 66a0de3c..54c64d97 100644 --- a/R/boundsPredprob.R +++ b/R/boundsPredprob.R @@ -1,38 +1,36 @@ -#' Decision cutpoints for boundary (based on predictive probability) +#' Decision cutpoints for boundary (based on predictive probability) for Decision 1 rule. #' #' This function is used to identify the efficacy boundary and futility -#' boundary based on predictive probabilities, i.e.: +#' boundary based on the following rules: #' Efficacy boundary: find minimum x (xU) where -#' Pr(Pr(P > p | x, Y) >= tT | x) > phiU, +#' Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, #' Futility boundary: find maximum x (xL) where -#' Pr(Pr(P > p | x, Y) >= tT | x) < phiL +#' Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL #' -#' @param nvec a vector of number of patients -#' @param Nmax maximum number of patients at the end of the trial -#' (default: maximum of \code{nvec}) -#' @param p threshold on the response rate -#' @param tT threshold on the posterior probability to be above p -#' @param phiL futility boundary predictive probability threshold -#' @param phiU efficacy boundary predictive probability threshold -#' @param a the alpha parameter of a beta prior of treatment group -#' @param b the beta parameter of a beta prior of treatment group -#' @return A matrix where for each sample size in \code{nvec}, this function -#' returns the maximum number of responses that meet the futility -#' threshold (xL), its corresponding response rate (pL), predictive probability -#' (ppL) and posterior probability (postL), the upper bound of one -#' sided 95% CI for the response rate based on an -#' exact binomial test (UciL), and the same boundary parameters for efficacy: -#' the minimal number of responses that meet the efficacy threshold (xU), -#' the corresponding response rate (pU), predictive probability -#' (ppL) and posterior probability (postU), the lower bound of one sided -#' 95% CI for the response rate based on exact binomial test (LciU). +#' @inheritParams predprob +#' @inheritParams ocPredprob +#' @inheritParams boundsPostprob +#' @return A matrix for each same size in `nvec`. For each sample size, the following is returned: +#' - `xL` : the maximum number of responses that meet the futility. +#' threshold +#' - `pL` : response rate corresponding to `xL`. +#' - `ppL` : predictive probability corresponding to `xL` +#' - `postL`: posterior probability corresponding to `xL`. +#' - `Ucil` : upper bound of one sided 95% CI for the response rate based on an +#' exact binomial test. +#' - `xU` : the minimal number of responses that meet the efficacy threshold. +#' - `pU` : response rate corresponding to `xU`. +#' - `postL`: posterior probability corresponding to `xU`. +#' - `ppU` : predictive probability corresponding to `xU` +#' - `LciU` : lower bound of one sided 95% CI for the response rate based on exact +#' binomial test. #' #' @importFrom stats binom.test #' #' @example examples/boundsPredprob.R #' @export #' @keywords graphics -boundsPredprob <- function(nvec, Nmax = max(nvec), p, tT, phiL, phiU, a, b) { +boundsPredprob <- function(nvec, Nmax = max(nvec), p0, tT, phiL, phiU, a, b) { znames <- c( "xL", "pL", "ppL", "postL", "UciL", "xU", "pU", "ppU", "postU", "LciU" @@ -46,29 +44,42 @@ boundsPredprob <- function(nvec, Nmax = max(nvec), p, tT, phiL, phiU, a, b) { xL <- NA xU <- NA for (x in 0:n) { - pp <- predprob(x, n, Nmax, p, tT, parE = c(a, b))$result + pp <- predprob(x, n, Nmax, p0, tT, parE = c(a, b))$result if (pp <= phiL) { xL <- x + ppL <- pp } if (pp >= phiU) { xU <- x + ppU <- ppL # done: leave innermost for loop break } } - # reset xU to NA if phiU=1 and n p | x, Y) >= tT | x) > phiU, +Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, Futility boundary: find maximum x (xL) where -Pr(Pr(P > p | x, Y) >= tT | x) < phiL +Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL } \examples{ -## 40 pts trial with interim looks after each 10 pts., -## final efficacy decision if more than 80\% probability to be above 20\% ORR, -## final futility decision otherwise. -## Interim efficacy decision if more than 90\% predictive probability reach this, -## interim futility decision if less than 10\% predictive probability. -## Uniform prior (i.e. beta(1, 1)) on the ORR: +# 40 pts trial with interim looks after each 10 pts., +# final efficacy decision if more than 80\% probability to be above 20\% ORR, +# final futility decision otherwise. +# Interim efficacy decision if more than 90\% predictive probability reach this, +# interim futility decision if less than 10\% predictive probability. +# Uniform prior (i.e. beta(1, 1)) on the ORR: boundsPredprob( nvec = c(10, 20, 30, 40), p = 0.20, tT = 0.80, phiL = 0.10, phiU = 0.90, a = 1, b = 1 ) -## From this we see e.g. that at the first IA at 10 pts, we would stop for futility -## if no patient responded, and for efficacy if 4 or more pts responded. +# From this we see e.g. that at the first IA at 10 pts, we would stop for futility +# if no patient responded, and for efficacy if 4 or more pts responded. } \keyword{graphics} diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 25c8d9e2..fa79aa7c 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,3 +117,124 @@ The criteria for Decision 2 for Futility looks are : } } } +\examples{ +# Here we illustrate an example for Decision 1 with the following assumptions : +# True response rate or truep of the treatment group = 40\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 1 with no wiggle. +set.seed(20) +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 100, + wiggle = FALSE, + decision1 = TRUE +) +result$oc + +# Decision 1 with wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Here we illustrate an example for Decision 2 with the following assumptions : +# True response rate or truep of the treatment group = 60\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 2 without wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiU = 0.8, + phiFu = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 20), + decision1 = FALSE +) +result$oc + +# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiL = 0.8, + phiU = 0.8, + parE = c(11, 19), + sim = 50, + wiggle = TRUE, + nnF = 30, + decision1 = FALSE +) +result$oc +} diff --git a/tests/testthat/test-boundsPredprob.R b/tests/testthat/test-boundsPredprob.R new file mode 100644 index 00000000..5d43c25f --- /dev/null +++ b/tests/testthat/test-boundsPredprob.R @@ -0,0 +1,33 @@ +# boundsPostProb ---- +test_that("boundsPredprob gives correct result and list", { + result <- boundsPredprob( + nvec = c(10, 20, 30, 40), + p0 = 0.2, + tT = 0.80, + phiL = 0.10, + phiU = 0.90, + a = 1, + b = 1 + ) + expected <- data.frame( + list( + nvec = c(10, 20, 30, 40), + xL = c(0, 2, 5, 9), + pL = c(0, 0.1, 0.1667, 0.225), + postL = c(0.0859, 0.1787, 0.3931, 0.704), + UciL = c(0.2589, 0.2826, 0.319, 0.3598), + xU = c(4, 7, 9, 10), + pU = c(0.4, 0.35, 0.3, 0.25), + postU = c(0.9496, 0.9569, 0.9254, 0.8177), + LciU = c(0.15, 0.1773, 0.1663, 0.1424) + ) + ) + expect_equal(result$xL, c(0, 2, 5, 9)) + expect_equal(result$pL, c(0, 0.1, 0.1667, 0.225)) + expect_equal(result$postL, c(0.0859, 0.1787, 0.3931, 0.704)) + expect_equal(result$UciL, c(0.2589, 0.2826, 0.319, 0.3598)) + expect_equal(result$xU, c(4, 7, 9, 10)) + expect_equal(result$pU, c(0.4, 0.35, 0.3, 0.25)) + expect_equal(result$postU, c(0.9496, 0.9569, 0.9254, 0.8177)) + expect_equal(result$LciU, c(0.15, 0.1773, 0.1663, 0.1424)) +}) From 7e605bf8e54295e184d77bc75f0e436f514e8a1e Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 26 May 2024 17:54:06 +0000 Subject: [PATCH 02/19] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/ocPredprob.Rd | 121 ---------------------------------------------- 1 file changed, 121 deletions(-) diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index fa79aa7c..25c8d9e2 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,124 +117,3 @@ The criteria for Decision 2 for Futility looks are : } } } -\examples{ -# Here we illustrate an example for Decision 1 with the following assumptions : -# True response rate or truep of the treatment group = 40\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 1 with no wiggle. -set.seed(20) -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 100, - wiggle = FALSE, - decision1 = TRUE -) -result$oc - -# Decision 1 with wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Here we illustrate an example for Decision 2 with the following assumptions : -# True response rate or truep of the treatment group = 60\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 2 without wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiU = 0.8, - phiFu = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 20), - decision1 = FALSE -) -result$oc - -# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiL = 0.8, - phiU = 0.8, - parE = c(11, 19), - sim = 50, - wiggle = TRUE, - nnF = 30, - decision1 = FALSE -) -result$oc -} From 3aa565b5a47b5d9822bc7d37ae947e8e92477e80 Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Tue, 11 Jun 2024 16:05:29 +0200 Subject: [PATCH 03/19] clean --- R/boundsPredprob.R | 11 +++-- man/ocPredprob.Rd | 121 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 5 deletions(-) diff --git a/R/boundsPredprob.R b/R/boundsPredprob.R index 54c64d97..7b550341 100644 --- a/R/boundsPredprob.R +++ b/R/boundsPredprob.R @@ -45,13 +45,14 @@ boundsPredprob <- function(nvec, Nmax = max(nvec), p0, tT, phiL, phiU, a, b) { xU <- NA for (x in 0:n) { pp <- predprob(x, n, Nmax, p0, tT, parE = c(a, b))$result - if (pp <= phiL) { - xL <- x - ppL <- pp - } - if (pp >= phiU) { + if (pp >= phiU) { # Efficacy look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, xU <- x ppU <- ppL + } + predprob(x, n, Nmax, p0, tT, parE = c(a, b))$result + if (pp <= phiL) { # Futility look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL + xL <- x + ppL <- pp # done: leave innermost for loop break } diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 25c8d9e2..63e17a09 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,3 +117,124 @@ The criteria for Decision 2 for Futility looks are : } } } +\examples{ +# Here we illustrate an example for Decision 1 with the following assumptions : +# True response rate or truep of the treatment group = 40\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 1 with no wiggle. +set.seed(20) +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + decision1 = TRUE +) +result$oc + +# Decision 1 with wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Here we illustrate an example for Decision 2 with the following assumptions : +# True response rate or truep of the treatment group = 60\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 2 without wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiU = 0.8, + phiFu = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 20), + decision1 = FALSE +) +result$oc + +# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiL = 0.8, + phiU = 0.8, + parE = c(11, 19), + sim = 50, + wiggle = TRUE, + nnF = 30, + decision1 = FALSE +) +result$oc +} From 7e50f1cff148860950d9bb62fe7de06ac0c04063 Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:08:22 +0000 Subject: [PATCH 04/19] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/ocPredprob.Rd | 121 ---------------------------------------------- 1 file changed, 121 deletions(-) diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 63e17a09..25c8d9e2 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,124 +117,3 @@ The criteria for Decision 2 for Futility looks are : } } } -\examples{ -# Here we illustrate an example for Decision 1 with the following assumptions : -# True response rate or truep of the treatment group = 40\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 1 with no wiggle. -set.seed(20) -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - decision1 = TRUE -) -result$oc - -# Decision 1 with wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Here we illustrate an example for Decision 2 with the following assumptions : -# True response rate or truep of the treatment group = 60\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 2 without wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiU = 0.8, - phiFu = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 20), - decision1 = FALSE -) -result$oc - -# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiL = 0.8, - phiU = 0.8, - parE = c(11, 19), - sim = 50, - wiggle = TRUE, - nnF = 30, - decision1 = FALSE -) -result$oc -} From 75b676e430619303f3d944fd2a10e8cd41fc7372 Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Wed, 26 Jun 2024 16:05:38 +0200 Subject: [PATCH 05/19] it works --- R/boundsPostprob.R | 21 ++++--- R/boundsPredprob.R | 14 ++--- examples/boundsPredprob.R | 25 +++++--- man/boundsPredprob.Rd | 25 +++++--- man/ocPredprob.Rd | 121 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 172 insertions(+), 34 deletions(-) diff --git a/R/boundsPostprob.R b/R/boundsPostprob.R index 09822eda..ee7e37fc 100644 --- a/R/boundsPostprob.R +++ b/R/boundsPostprob.R @@ -29,15 +29,22 @@ #' @export #' @keywords graphics boundsPostprob <- function(nvec, p0, p1 = p0, tL, tU, a, b) { - z <- matrix(NA, length(nvec), 6) - dimnames(z) <- list(nvec, c( - "xL", "pL", "postL", - "xU", "pU", "postU" - )) + z <- matrix(NA, length(nvec), ncol = 6) + # dimnames(z) <- list(nvec, c( + # "xL", "pL", "postL", + # "xU", "pU", "postU" + # )) + # znames <- c( + # "xL", "pL", "postL", "UciL", + # "xU", "pU", "postU", "LciU" + # ) + znames <- c( - "xL", "pL", "postL", "UciL", - "xU", "pU", "postU", "LciU" + "xL", "pL", "postL", "pL_upper_ci", + "xU", "pU", "postU", "pU_lower_ci" ) + dimnames(z) <- list(nvec, znames) + z <- matrix(NA, length(nvec), length(znames)) dimnames(z) <- list(nvec, znames) k <- 0 diff --git a/R/boundsPredprob.R b/R/boundsPredprob.R index 7b550341..b926dfcc 100644 --- a/R/boundsPredprob.R +++ b/R/boundsPredprob.R @@ -45,15 +45,13 @@ boundsPredprob <- function(nvec, Nmax = max(nvec), p0, tT, phiL, phiU, a, b) { xU <- NA for (x in 0:n) { pp <- predprob(x, n, Nmax, p0, tT, parE = c(a, b))$result - if (pp >= phiU) { # Efficacy look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, - xU <- x - ppU <- ppL - } - predprob(x, n, Nmax, p0, tT, parE = c(a, b))$result - if (pp <= phiL) { # Futility look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL + if (pp <= phiL) { # Futility look, Rule Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL xL <- x ppL <- pp - # done: leave innermost for loop + } + if (pp >= phiU) { # Efficacy look, Rule Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, + xU <- x + ppU <- pp break } } @@ -62,8 +60,6 @@ boundsPredprob <- function(nvec, Nmax = max(nvec), p0, tT, phiL, phiU, a, b) { xU <- NA } # calculate predictive and posterior probabilities at boundaries - ppL <- predprob(xL, n, Nmax, p0, tT, parE = c(a, b))$result - ppU <- predprob(xU, n, Nmax, p0, tT, parE = c(a, b))$result postL <- postprob(xL, n, p0, parE = c(a, b)) postU <- postprob(xU, n, p0, parE = c(a, b)) # calculate lower CI at boundaries diff --git a/examples/boundsPredprob.R b/examples/boundsPredprob.R index 862d627c..5b56c681 100644 --- a/examples/boundsPredprob.R +++ b/examples/boundsPredprob.R @@ -1,12 +1,19 @@ -# 40 pts trial with interim looks after each 10 pts., -# final efficacy decision if more than 80% probability to be above 20% ORR, -# final futility decision otherwise. -# Interim efficacy decision if more than 90% predictive probability reach this, -# interim futility decision if less than 10% predictive probability. +# 40 pts trial with interim looks after each 10 patients. +# Final efficacy decision if more than 80% probability to be above 20% ORR, +# Final futility decision otherwise. +# Interim efficacy decision if more than 90% predictive probability reach this or +# Efficacy look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, +# Interim futility decision if less than 10% predictive probability or +# Futility look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL # Uniform prior (i.e. beta(1, 1)) on the ORR: boundsPredprob( - nvec = c(10, 20, 30, 40), p = 0.20, tT = 0.80, - phiL = 0.10, phiU = 0.90, a = 1, b = 1 + nvec = c(10, 20, 30, 40), + p = 0.20, + tT = 0.80, + phiL = 0.10, + phiU = 0.90, + a = 1, + b = 1 ) -# From this we see e.g. that at the first IA at 10 pts, we would stop for futility -# if no patient responded, and for efficacy if 4 or more pts responded. +# From this we see e.g. that at the first IA at 10 patients, we would stop for futility +# if no patient responded, and for efficacy if 4 or more patients responded. diff --git a/man/boundsPredprob.Rd b/man/boundsPredprob.Rd index 9043ad3b..8c2fd728 100644 --- a/man/boundsPredprob.Rd +++ b/man/boundsPredprob.Rd @@ -50,17 +50,24 @@ Futility boundary: find maximum x (xL) where Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL } \examples{ -# 40 pts trial with interim looks after each 10 pts., -# final efficacy decision if more than 80\% probability to be above 20\% ORR, -# final futility decision otherwise. -# Interim efficacy decision if more than 90\% predictive probability reach this, -# interim futility decision if less than 10\% predictive probability. +# 40 pts trial with interim looks after each 10 patients. +# Final efficacy decision if more than 80\% probability to be above 20\% ORR, +# Final futility decision otherwise. +# Interim efficacy decision if more than 90\% predictive probability reach this or +# Efficacy look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, +# Interim futility decision if less than 10\% predictive probability or +# Futility look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL # Uniform prior (i.e. beta(1, 1)) on the ORR: boundsPredprob( - nvec = c(10, 20, 30, 40), p = 0.20, tT = 0.80, - phiL = 0.10, phiU = 0.90, a = 1, b = 1 + nvec = c(10, 20, 30, 40), + p = 0.20, + tT = 0.80, + phiL = 0.10, + phiU = 0.90, + a = 1, + b = 1 ) -# From this we see e.g. that at the first IA at 10 pts, we would stop for futility -# if no patient responded, and for efficacy if 4 or more pts responded. +# From this we see e.g. that at the first IA at 10 patients, we would stop for futility +# if no patient responded, and for efficacy if 4 or more patients responded. } \keyword{graphics} diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 25c8d9e2..63e17a09 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,3 +117,124 @@ The criteria for Decision 2 for Futility looks are : } } } +\examples{ +# Here we illustrate an example for Decision 1 with the following assumptions : +# True response rate or truep of the treatment group = 40\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 1 with no wiggle. +set.seed(20) +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + decision1 = TRUE +) +result$oc + +# Decision 1 with wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Here we illustrate an example for Decision 2 with the following assumptions : +# True response rate or truep of the treatment group = 60\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 2 without wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiU = 0.8, + phiFu = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 20), + decision1 = FALSE +) +result$oc + +# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiL = 0.8, + phiU = 0.8, + parE = c(11, 19), + sim = 50, + wiggle = TRUE, + nnF = 30, + decision1 = FALSE +) +result$oc +} From a5134f048f15efc3c8561d2963a493c1657871f7 Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:07:33 +0000 Subject: [PATCH 06/19] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/ocPredprob.Rd | 121 ---------------------------------------------- 1 file changed, 121 deletions(-) diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 63e17a09..25c8d9e2 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,124 +117,3 @@ The criteria for Decision 2 for Futility looks are : } } } -\examples{ -# Here we illustrate an example for Decision 1 with the following assumptions : -# True response rate or truep of the treatment group = 40\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 1 with no wiggle. -set.seed(20) -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - decision1 = TRUE -) -result$oc - -# Decision 1 with wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Here we illustrate an example for Decision 2 with the following assumptions : -# True response rate or truep of the treatment group = 60\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 2 without wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiU = 0.8, - phiFu = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 20), - decision1 = FALSE -) -result$oc - -# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiL = 0.8, - phiU = 0.8, - parE = c(11, 19), - sim = 50, - wiggle = TRUE, - nnF = 30, - decision1 = FALSE -) -result$oc -} From 1b7df2697ce351ea4ad26de0783ebb9bb0af9e96 Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Thu, 26 Sep 2024 08:19:07 +0200 Subject: [PATCH 07/19] some syntax changes --- R/boundsPredprob.R | 16 +++--- man/boundsPredprob.Rd | 11 ++-- man/ocPredprob.Rd | 121 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 13 deletions(-) diff --git a/R/boundsPredprob.R b/R/boundsPredprob.R index b926dfcc..1fd99ae4 100644 --- a/R/boundsPredprob.R +++ b/R/boundsPredprob.R @@ -10,7 +10,7 @@ #' @inheritParams predprob #' @inheritParams ocPredprob #' @inheritParams boundsPostprob -#' @return A matrix for each same size in `nvec`. For each sample size, the following is returned: +#' @return A matrix for each same size in `looks`. For each sample size, the following is returned: #' - `xL` : the maximum number of responses that meet the futility. #' threshold #' - `pL` : response rate corresponding to `xL`. @@ -30,15 +30,19 @@ #' @example examples/boundsPredprob.R #' @export #' @keywords graphics -boundsPredprob <- function(nvec, Nmax = max(nvec), p0, tT, phiL, phiU, a, b) { +boundsPredprob <- function(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE) { znames <- c( "xL", "pL", "ppL", "postL", "UciL", "xU", "pU", "ppU", "postU", "LciU" ) - z <- matrix(NA, length(nvec), length(znames)) - dimnames(z) <- list(nvec, znames) + z <- matrix(NA, length(looks), length(znames)) + dimnames(z) <- list(looks, znames) + parE <- t(parE) + if (missing(weights)) { + weights <- rep(1, nrow(parE)) + } k <- 0 - for (n in nvec) { + for (n in looks) { k <- k + 1 # initialize so will return NA if 0 or n in "continue" region xL <- NA @@ -78,5 +82,5 @@ boundsPredprob <- function(nvec, Nmax = max(nvec), p0, tT, phiL, phiU, a, b) { LciU ) } - return(round(data.frame(nvec, z), 4)) + return(round(data.frame(looks, z), 4)) } diff --git a/man/boundsPredprob.Rd b/man/boundsPredprob.Rd index 8c2fd728..ecd65eb5 100644 --- a/man/boundsPredprob.Rd +++ b/man/boundsPredprob.Rd @@ -4,11 +4,9 @@ \alias{boundsPredprob} \title{Decision cutpoints for boundary (based on predictive probability) for Decision 1 rule.} \usage{ -boundsPredprob(nvec, Nmax = max(nvec), p0, tT, phiL, phiU, a, b) +boundsPredprob(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE) } \arguments{ -\item{nvec}{a vector of number of patients} - \item{Nmax}{(\code{number}):\cr maximum number of patients at the end of the trial in the \code{E} group.} \item{p0}{(\code{number}):\cr lower Futility threshold of response rate.} @@ -19,12 +17,11 @@ boundsPredprob(nvec, Nmax = max(nvec), p0, tT, phiL, phiU, a, b) \item{phiU}{(\code{number}):\cr upper threshold on the predictive probability.} -\item{a}{the alpha parameter of the beta prior of treatment group} - -\item{b}{the beta parameter of the beta prior of treatment group} +\item{parE}{(\code{numeric}):\cr the beta parameters matrix, with K rows and 2 columns, +corresponding to the beta parameters of the K components.} } \value{ -A matrix for each same size in \code{nvec}. For each sample size, the following is returned: +A matrix for each same size in \code{looks}. For each sample size, the following is returned: \itemize{ \item \code{xL} : the maximum number of responses that meet the futility. threshold diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 25c8d9e2..63e17a09 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,3 +117,124 @@ The criteria for Decision 2 for Futility looks are : } } } +\examples{ +# Here we illustrate an example for Decision 1 with the following assumptions : +# True response rate or truep of the treatment group = 40\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 1 with no wiggle. +set.seed(20) +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + decision1 = TRUE +) +result$oc + +# Decision 1 with wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Here we illustrate an example for Decision 2 with the following assumptions : +# True response rate or truep of the treatment group = 60\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 2 without wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiU = 0.8, + phiFu = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 20), + decision1 = FALSE +) +result$oc + +# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiL = 0.8, + phiU = 0.8, + parE = c(11, 19), + sim = 50, + wiggle = TRUE, + nnF = 30, + decision1 = FALSE +) +result$oc +} From bdcf2a393b6808b3be63862f7452b9c1d5fc74ed Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 26 Sep 2024 06:22:27 +0000 Subject: [PATCH 08/19] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- DESCRIPTION | 2 +- man/ocPredprob.Rd | 121 ---------------------------------------------- 2 files changed, 1 insertion(+), 122 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index b568d599..d7f95063 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -44,7 +44,7 @@ Language: en-US LazyData: true Roxygen: list(markdown = TRUE, packages = "roxytypes") -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 Config/Needs/documentation: roxytypes Remotes: diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 63e17a09..25c8d9e2 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,124 +117,3 @@ The criteria for Decision 2 for Futility looks are : } } } -\examples{ -# Here we illustrate an example for Decision 1 with the following assumptions : -# True response rate or truep of the treatment group = 40\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 1 with no wiggle. -set.seed(20) -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - decision1 = TRUE -) -result$oc - -# Decision 1 with wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Here we illustrate an example for Decision 2 with the following assumptions : -# True response rate or truep of the treatment group = 60\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 2 without wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiU = 0.8, - phiFu = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 20), - decision1 = FALSE -) -result$oc - -# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiL = 0.8, - phiU = 0.8, - parE = c(11, 19), - sim = 50, - wiggle = TRUE, - nnF = 30, - decision1 = FALSE -) -result$oc -} From e180429f76b5f19b5f26dbb2622a958740370af5 Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Fri, 27 Sep 2024 10:58:14 +0200 Subject: [PATCH 09/19] clean --- R/boundsPredprob.R | 35 ++++---- examples/boundsPredprob.R | 8 +- man/boundsPredprob.Rd | 25 ++++-- man/ocPredprob.Rd | 121 +++++++++++++++++++++++++++ tests/testthat/test-boundsPredprob.R | 7 +- 5 files changed, 164 insertions(+), 32 deletions(-) diff --git a/R/boundsPredprob.R b/R/boundsPredprob.R index 1fd99ae4..27e916b9 100644 --- a/R/boundsPredprob.R +++ b/R/boundsPredprob.R @@ -14,14 +14,14 @@ #' - `xL` : the maximum number of responses that meet the futility. #' threshold #' - `pL` : response rate corresponding to `xL`. -#' - `ppL` : predictive probability corresponding to `xL` +#' - `predL` : predictive probability corresponding to `xL` #' - `postL`: posterior probability corresponding to `xL`. #' - `Ucil` : upper bound of one sided 95% CI for the response rate based on an #' exact binomial test. #' - `xU` : the minimal number of responses that meet the efficacy threshold. #' - `pU` : response rate corresponding to `xU`. +#' - `predU` : predictive probability corresponding to `xU` #' - `postL`: posterior probability corresponding to `xU`. -#' - `ppU` : predictive probability corresponding to `xU` #' - `LciU` : lower bound of one sided 95% CI for the response rate based on exact #' binomial test. #' @@ -30,32 +30,37 @@ #' @example examples/boundsPredprob.R #' @export #' @keywords graphics -boundsPredprob <- function(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE) { +boundsPredprob <- function(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE = c(1, 1), weights) { + assert_numeric(looks) + assert_number(p0, lower = 0, upper = 1) + assert_number(tT, lower = 0, upper = 1) + assert_numeric(parE, min.len = 2, any.missing = FALSE) znames <- c( - "xL", "pL", "ppL", "postL", "UciL", - "xU", "pU", "ppU", "postU", "LciU" + "xL", "pL", "predL", "postL", "UciL", + "xU", "pU", "predU", "postU", "LciU" ) z <- matrix(NA, length(looks), length(znames)) dimnames(z) <- list(looks, znames) + k <- 0 parE <- t(parE) if (missing(weights)) { weights <- rep(1, nrow(parE)) } - k <- 0 + assert_numeric(weights, min.len = 0, len = nrow(par), finite = TRUE) for (n in looks) { k <- k + 1 # initialize so will return NA if 0 or n in "continue" region xL <- NA xU <- NA for (x in 0:n) { - pp <- predprob(x, n, Nmax, p0, tT, parE = c(a, b))$result - if (pp <= phiL) { # Futility look, Rule Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL + predprob <- predprob(x, n, Nmax, p0, tT, parE = parE)$result + if (predprob <= phiL) { # Futility look, Rule Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL xL <- x - ppL <- pp + predL <- predprob } - if (pp >= phiU) { # Efficacy look, Rule Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, + if (predprob >= phiU) { # Efficacy look, Rule Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, xU <- x - ppU <- pp + predU <- predprob break } } @@ -64,20 +69,20 @@ boundsPredprob <- function(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE) { xU <- NA } # calculate predictive and posterior probabilities at boundaries - postL <- postprob(xL, n, p0, parE = c(a, b)) - postU <- postprob(xU, n, p0, parE = c(a, b)) + postL <- postprob(xL, n, p0, parE = parE) + postU <- postprob(xU, n, p0, parE = parE) # calculate lower CI at boundaries UciL <- ifelse(!is.na(xL), stats::binom.test(xL, n, alt = "less")$conf.int[2], NA) LciU <- ifelse(!is.na(xU), stats::binom.test(xU, n, alt = "greater")$conf.int[1], NA) z[k, ] <- c( xL, xL / n, - ppL, + predL, postL, UciL, xU, xU / n, - ppU, + predU, postU, LciU ) diff --git a/examples/boundsPredprob.R b/examples/boundsPredprob.R index 5b56c681..25fcf729 100644 --- a/examples/boundsPredprob.R +++ b/examples/boundsPredprob.R @@ -7,13 +7,11 @@ # Futility look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL # Uniform prior (i.e. beta(1, 1)) on the ORR: boundsPredprob( - nvec = c(10, 20, 30, 40), - p = 0.20, + looks = c(10, 20, 30, 40), + p0 = 0.20, tT = 0.80, phiL = 0.10, - phiU = 0.90, - a = 1, - b = 1 + phiU = 0.90 ) # From this we see e.g. that at the first IA at 10 patients, we would stop for futility # if no patient responded, and for efficacy if 4 or more patients responded. diff --git a/man/boundsPredprob.Rd b/man/boundsPredprob.Rd index ecd65eb5..abd3a8ce 100644 --- a/man/boundsPredprob.Rd +++ b/man/boundsPredprob.Rd @@ -4,7 +4,16 @@ \alias{boundsPredprob} \title{Decision cutpoints for boundary (based on predictive probability) for Decision 1 rule.} \usage{ -boundsPredprob(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE) +boundsPredprob( + looks, + Nmax = max(looks), + p0, + tT, + phiL, + phiU, + parE = c(1, 1), + weights +) } \arguments{ \item{Nmax}{(\code{number}):\cr maximum number of patients at the end of the trial in the \code{E} group.} @@ -19,6 +28,8 @@ boundsPredprob(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE) \item{parE}{(\code{numeric}):\cr the beta parameters matrix, with K rows and 2 columns, corresponding to the beta parameters of the K components.} + +\item{weights}{(\code{numeric}):\cr the mixture weights of the beta mixture prior.} } \value{ A matrix for each same size in \code{looks}. For each sample size, the following is returned: @@ -26,14 +37,14 @@ A matrix for each same size in \code{looks}. For each sample size, the following \item \code{xL} : the maximum number of responses that meet the futility. threshold \item \code{pL} : response rate corresponding to \code{xL}. -\item \code{ppL} : predictive probability corresponding to \code{xL} +\item \code{predL} : predictive probability corresponding to \code{xL} \item \code{postL}: posterior probability corresponding to \code{xL}. \item \code{Ucil} : upper bound of one sided 95\% CI for the response rate based on an exact binomial test. \item \code{xU} : the minimal number of responses that meet the efficacy threshold. \item \code{pU} : response rate corresponding to \code{xU}. +\item \code{predU} : predictive probability corresponding to \code{xU} \item \code{postL}: posterior probability corresponding to \code{xU}. -\item \code{ppU} : predictive probability corresponding to \code{xU} \item \code{LciU} : lower bound of one sided 95\% CI for the response rate based on exact binomial test. } @@ -56,13 +67,11 @@ Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL # Futility look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL # Uniform prior (i.e. beta(1, 1)) on the ORR: boundsPredprob( - nvec = c(10, 20, 30, 40), - p = 0.20, + looks = c(10, 20, 30, 40), + p0 = 0.20, tT = 0.80, phiL = 0.10, - phiU = 0.90, - a = 1, - b = 1 + phiU = 0.90 ) # From this we see e.g. that at the first IA at 10 patients, we would stop for futility # if no patient responded, and for efficacy if 4 or more patients responded. diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 25c8d9e2..63e17a09 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,3 +117,124 @@ The criteria for Decision 2 for Futility looks are : } } } +\examples{ +# Here we illustrate an example for Decision 1 with the following assumptions : +# True response rate or truep of the treatment group = 40\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 1 with no wiggle. +set.seed(20) +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + decision1 = TRUE +) +result$oc + +# Decision 1 with wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Here we illustrate an example for Decision 2 with the following assumptions : +# True response rate or truep of the treatment group = 60\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 2 without wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiU = 0.8, + phiFu = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 20), + decision1 = FALSE +) +result$oc + +# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiL = 0.8, + phiU = 0.8, + parE = c(11, 19), + sim = 50, + wiggle = TRUE, + nnF = 30, + decision1 = FALSE +) +result$oc +} diff --git a/tests/testthat/test-boundsPredprob.R b/tests/testthat/test-boundsPredprob.R index 5d43c25f..4c8b17e0 100644 --- a/tests/testthat/test-boundsPredprob.R +++ b/tests/testthat/test-boundsPredprob.R @@ -1,13 +1,12 @@ # boundsPostProb ---- -test_that("boundsPredprob gives correct result and list", { +test_that("boundsPredprob gives correct result", { result <- boundsPredprob( - nvec = c(10, 20, 30, 40), + looks = c(10, 20, 30, 40), p0 = 0.2, tT = 0.80, phiL = 0.10, phiU = 0.90, - a = 1, - b = 1 + parE = c(1, 1) ) expected <- data.frame( list( From 942e0f7b2936b25ad0bdcb8eaf4306bf99585214 Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 09:01:32 +0000 Subject: [PATCH 10/19] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/ocPredprob.Rd | 121 ---------------------------------------------- 1 file changed, 121 deletions(-) diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 63e17a09..25c8d9e2 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,124 +117,3 @@ The criteria for Decision 2 for Futility looks are : } } } -\examples{ -# Here we illustrate an example for Decision 1 with the following assumptions : -# True response rate or truep of the treatment group = 40\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 1 with no wiggle. -set.seed(20) -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - decision1 = TRUE -) -result$oc - -# Decision 1 with wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Here we illustrate an example for Decision 2 with the following assumptions : -# True response rate or truep of the treatment group = 60\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 2 without wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiU = 0.8, - phiFu = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 20), - decision1 = FALSE -) -result$oc - -# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiL = 0.8, - phiU = 0.8, - parE = c(11, 19), - sim = 50, - wiggle = TRUE, - nnF = 30, - decision1 = FALSE -) -result$oc -} From 23a06f30b1d4bf01fc48be982bc4c0fc4f6d5ba7 Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Sat, 28 Sep 2024 00:26:36 +0200 Subject: [PATCH 11/19] clean --- man/ocPredprob.Rd | 121 +++++++++++++++++++++++++++ tests/testthat/test-boundsPredprob.R | 33 ++++++++ 2 files changed, 154 insertions(+) diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 25c8d9e2..63e17a09 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,3 +117,124 @@ The criteria for Decision 2 for Futility looks are : } } } +\examples{ +# Here we illustrate an example for Decision 1 with the following assumptions : +# True response rate or truep of the treatment group = 40\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 1 with no wiggle. +set.seed(20) +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + decision1 = TRUE +) +result$oc + +# Decision 1 with wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Here we illustrate an example for Decision 2 with the following assumptions : +# True response rate or truep of the treatment group = 60\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 2 without wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiU = 0.8, + phiFu = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 20), + decision1 = FALSE +) +result$oc + +# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiL = 0.8, + phiU = 0.8, + parE = c(11, 19), + sim = 50, + wiggle = TRUE, + nnF = 30, + decision1 = FALSE +) +result$oc +} diff --git a/tests/testthat/test-boundsPredprob.R b/tests/testthat/test-boundsPredprob.R index 4c8b17e0..928b60e7 100644 --- a/tests/testthat/test-boundsPredprob.R +++ b/tests/testthat/test-boundsPredprob.R @@ -30,3 +30,36 @@ test_that("boundsPredprob gives correct result", { expect_equal(result$postU, c(0.9496, 0.9569, 0.9254, 0.8177)) expect_equal(result$LciU, c(0.15, 0.1773, 0.1663, 0.1424)) }) + +test_that("boundsPredprob of beta mixture gives correct result", { + result <- boundsPredprob( + looks = c(7, 15, 20), + p0 = 0.2, + tT = 0.80, + phiL = 0.10, + phiU = 0.90, + parE = rbind(c(1, 1), c(3, 10)), + weights = c(0.2, 0.8) + ) + expected <- data.frame( + list( + nvec = c(10, 20, 30, 40), + xL = c(0, 2, 5, 9), + pL = c(0, 0.1, 0.1667, 0.225), + postL = c(0.0859, 0.1787, 0.3931, 0.704), + UciL = c(0.2589, 0.2826, 0.319, 0.3598), + xU = c(4, 7, 9, 10), + pU = c(0.4, 0.35, 0.3, 0.25), + postU = c(0.9496, 0.9569, 0.9254, 0.8177), + LciU = c(0.15, 0.1773, 0.1663, 0.1424) + ) + ) + expect_equal(result$xL, c(0, 2, 5, 9)) + expect_equal(result$pL, c(0, 0.1, 0.1667, 0.225)) + expect_equal(result$postL, c(0.0859, 0.1787, 0.3931, 0.704)) + expect_equal(result$UciL, c(0.2589, 0.2826, 0.319, 0.3598)) + expect_equal(result$xU, c(4, 7, 9, 10)) + expect_equal(result$pU, c(0.4, 0.35, 0.3, 0.25)) + expect_equal(result$postU, c(0.9496, 0.9569, 0.9254, 0.8177)) + expect_equal(result$LciU, c(0.15, 0.1773, 0.1663, 0.1424)) +}) From 9ffba4cd4430237a60d088ec9af11ca14202d2f2 Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:29:24 +0000 Subject: [PATCH 12/19] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/ocPredprob.Rd | 121 ---------------------------------------------- 1 file changed, 121 deletions(-) diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 63e17a09..25c8d9e2 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,124 +117,3 @@ The criteria for Decision 2 for Futility looks are : } } } -\examples{ -# Here we illustrate an example for Decision 1 with the following assumptions : -# True response rate or truep of the treatment group = 40\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 1 with no wiggle. -set.seed(20) -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - decision1 = TRUE -) -result$oc - -# Decision 1 with wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.4, - p0 = 0.25, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.4, - p0 = 0.25, - p1 = 0.2, - tT = 0.6, - phiL = 0.2, - phiU = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = TRUE, - nnF = c(10, 15, 20), - decision1 = TRUE -) -result$oc - -# Here we illustrate an example for Decision 2 with the following assumptions : -# True response rate or truep of the treatment group = 60\% -# The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT -# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu -# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. - -# Decision 2 without wiggle. -result <- ocPredprob( - nnE = c(10, 20), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiU = 0.8, - phiFu = 0.8, - parE = c(1, 1), - sim = 50, - wiggle = FALSE, - nnF = c(10, 20), - decision1 = FALSE -) -result$oc - -# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. -result <- ocPredprob( - nnE = c(10, 25, 30), - truep = 0.6, - p0 = 0.25, - p1 = 0.25, - tT = 0.6, - tF = 0.6, - phiL = 0.8, - phiU = 0.8, - parE = c(11, 19), - sim = 50, - wiggle = TRUE, - nnF = 30, - decision1 = FALSE -) -result$oc -} From f6faec2525fa0c5e0d337fe214debc5317236862 Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Tue, 1 Oct 2024 11:24:05 +0200 Subject: [PATCH 13/19] clean --- R/predprob.R | 2 +- examples/boundsPredprob.R | 22 ++++++- man/boundsPredprob.Rd | 22 ++++++- man/ocPredprob.Rd | 121 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 7 deletions(-) diff --git a/R/predprob.R b/R/predprob.R index 93329528..f550e018 100644 --- a/R/predprob.R +++ b/R/predprob.R @@ -63,7 +63,7 @@ predprob <- function(x, n, Nmax, p, thetaT, parE = c(1, 1), betamixPost, dbetabinomMix(x = 0:m, m = m, par = par, weights = weights) ) - assert_numeric(density, lower = 0, upper = 1, finite = TRUE, any.missing = FALSE) + assert_numeric(density, lower = 0, upper = 1 + .Machine$double.eps, finite = TRUE, any.missing = FALSE) assert_number(thetaT, lower = 0, upper = 1, finite = TRUE) # posterior probabilities to be above threshold p posterior <- postprob(x = x + c(0:m), n = Nmax, p = p, parE = parE, weights = weights) diff --git a/examples/boundsPredprob.R b/examples/boundsPredprob.R index 25fcf729..1150fd9a 100644 --- a/examples/boundsPredprob.R +++ b/examples/boundsPredprob.R @@ -10,8 +10,24 @@ boundsPredprob( looks = c(10, 20, 30, 40), p0 = 0.20, tT = 0.80, - phiL = 0.10, + phiL = 0.60, phiU = 0.90 ) -# From this we see e.g. that at the first IA at 10 patients, we would stop for futility -# if no patient responded, and for efficacy if 4 or more patients responded. + +# 25 pts trial with interim looks at 7 and 15 pts. +# Efficacy decision if more than 80% probability to be above 20% ORR, +# Final futility decision otherwise. +# Interim efficacy decision if more than 90% predictive probability reach this or +# Efficacy look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, +# Interim futility decision if less than 60% predictive probability or +# Futility look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phi +# with mixed prior and weights: +boundsPredprob( + looks = c(7, 15, 25), + p0 = 0.20, + tT = 0.80, + phiL = 0.60, + phiU = 0.90, + parE = rbind(c(1, 1), c(3, 10)), + weights = c(0.2, 0.8) +) diff --git a/man/boundsPredprob.Rd b/man/boundsPredprob.Rd index abd3a8ce..0f082775 100644 --- a/man/boundsPredprob.Rd +++ b/man/boundsPredprob.Rd @@ -70,10 +70,26 @@ boundsPredprob( looks = c(10, 20, 30, 40), p0 = 0.20, tT = 0.80, - phiL = 0.10, + phiL = 0.60, phiU = 0.90 ) -# From this we see e.g. that at the first IA at 10 patients, we would stop for futility -# if no patient responded, and for efficacy if 4 or more patients responded. + +# 25 pts trial with interim looks at 7 and 15 pts. +# Efficacy decision if more than 80\% probability to be above 20\% ORR, +# Final futility decision otherwise. +# Interim efficacy decision if more than 90\% predictive probability reach this or +# Efficacy look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) >= phiU, +# Interim futility decision if less than 60\% predictive probability or +# Futility look Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phi +# with mixed prior and weights: +boundsPredprob( + looks = c(7, 15, 25), + p0 = 0.20, + tT = 0.80, + phiL = 0.60, + phiU = 0.90, + parE = rbind(c(1, 1), c(3, 10)), + weights = c(0.2, 0.8) +) } \keyword{graphics} diff --git a/man/ocPredprob.Rd b/man/ocPredprob.Rd index 25c8d9e2..63e17a09 100644 --- a/man/ocPredprob.Rd +++ b/man/ocPredprob.Rd @@ -117,3 +117,124 @@ The criteria for Decision 2 for Futility looks are : } } } +\examples{ +# Here we illustrate an example for Decision 1 with the following assumptions : +# True response rate or truep of the treatment group = 40\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate > p0) < tT +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 1 with no wiggle. +set.seed(20) +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + decision1 = TRUE +) +result$oc + +# Decision 1 with wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.4, + p0 = 0.25, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final without wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Decision 1 with separate Futility and Efficacy looks at interim and final with wiggle. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.4, + p0 = 0.25, + p1 = 0.2, + tT = 0.6, + phiL = 0.2, + phiU = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = TRUE, + nnF = c(10, 15, 20), + decision1 = TRUE +) +result$oc + +# Here we illustrate an example for Decision 2 with the following assumptions : +# True response rate or truep of the treatment group = 60\% +# The following are the Final Stop rules respectively : +# - Final look for Efficacy: Pr( response rate > 25\% ) > 60\% or P(response rate > p0) > tT +# - Final look for Futility: Pr( response rate < 25\% ) < 60\% or P(response rate < p1) > tF +# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) > 80\% or P(failure at final) > phiFu +# We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. + +# Decision 2 without wiggle. +result <- ocPredprob( + nnE = c(10, 20), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiU = 0.8, + phiFu = 0.8, + parE = c(1, 1), + sim = 50, + wiggle = FALSE, + nnF = c(10, 20), + decision1 = FALSE +) +result$oc + +# Decision 2 with wiggle and with Futility only at final with non-uniform beta prior parE. +result <- ocPredprob( + nnE = c(10, 25, 30), + truep = 0.6, + p0 = 0.25, + p1 = 0.25, + tT = 0.6, + tF = 0.6, + phiL = 0.8, + phiU = 0.8, + parE = c(11, 19), + sim = 50, + wiggle = TRUE, + nnF = 30, + decision1 = FALSE +) +result$oc +} From cefe1a93092cf6a2ffc14b4ac448e33cb7714d88 Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Tue, 1 Oct 2024 11:41:10 +0200 Subject: [PATCH 14/19] clean --- tests/testthat/test-boundsPredprob.R | 38 +++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/tests/testthat/test-boundsPredprob.R b/tests/testthat/test-boundsPredprob.R index 928b60e7..ae62fee8 100644 --- a/tests/testthat/test-boundsPredprob.R +++ b/tests/testthat/test-boundsPredprob.R @@ -43,23 +43,27 @@ test_that("boundsPredprob of beta mixture gives correct result", { ) expected <- data.frame( list( - nvec = c(10, 20, 30, 40), - xL = c(0, 2, 5, 9), - pL = c(0, 0.1, 0.1667, 0.225), - postL = c(0.0859, 0.1787, 0.3931, 0.704), - UciL = c(0.2589, 0.2826, 0.319, 0.3598), - xU = c(4, 7, 9, 10), - pU = c(0.4, 0.35, 0.3, 0.25), - postU = c(0.9496, 0.9569, 0.9254, 0.8177), - LciU = c(0.15, 0.1773, 0.1663, 0.1424) + looks = c(7, 15, 20), + xL = c(1, 3, 6), + pL = c(0.1429, 0.2000, 0.3000), + predL = c(0.0446, 0.0121, 0.0000), + postL = c(0.2407, 0.3818, 0.7734), + UciL = c(0.5207, 0.4398, 0.5078), + xU = c(5, 7, 7), + pU = c(0.7143, 0.4667, 0.3500), + predU = c(0.9843, 1.0000, 1.0000), + postU = c(0.9883, 0.9727, 0.8919), + LciU = c(0.3413, 0.2437, 0.1773) ) ) - expect_equal(result$xL, c(0, 2, 5, 9)) - expect_equal(result$pL, c(0, 0.1, 0.1667, 0.225)) - expect_equal(result$postL, c(0.0859, 0.1787, 0.3931, 0.704)) - expect_equal(result$UciL, c(0.2589, 0.2826, 0.319, 0.3598)) - expect_equal(result$xU, c(4, 7, 9, 10)) - expect_equal(result$pU, c(0.4, 0.35, 0.3, 0.25)) - expect_equal(result$postU, c(0.9496, 0.9569, 0.9254, 0.8177)) - expect_equal(result$LciU, c(0.15, 0.1773, 0.1663, 0.1424)) + expect_equal(result$xL, c(1, 3, 6)) + expect_equal(result$pL, c(0.1429, 0.2000, 0.3000)) + expect_equal(result$predL, c(0.0446, 0.0121, 0.0000)) + expect_equal(result$postL, c(0.2407, 0.3818, 0.7734)) + expect_equal(result$UciL, c(0.5207, 0.4398, 0.5078)) + expect_equal(result$xU, c(5, 7, 7)) + expect_equal(result$pU, c(0.7143, 0.4667, 0.3500)) + expect_equal(result$predU, c(0.9843, 1.0000, 1.0000)) + expect_equal(result$postU, c(0.9883, 0.9727, 0.8919)) + expect_equal(result$LciU, c(0.3413, 0.2437, 0.1773)) }) From aee5fb6b6595f949c3b4b92054e7b7e97520487d Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Wed, 2 Oct 2024 18:17:34 +0200 Subject: [PATCH 15/19] clean --- examples/ocPredprobDist.R | 22 +++++++++++++--------- examples/plotBounds.R | 8 -------- man/ocPredprobDist.Rd | 26 +++++++++++++++++--------- man/plotBounds.Rd | 8 -------- 4 files changed, 30 insertions(+), 34 deletions(-) diff --git a/examples/ocPredprobDist.R b/examples/ocPredprobDist.R index 4bc2715e..19982cf1 100644 --- a/examples/ocPredprobDist.R +++ b/examples/ocPredprobDist.R @@ -10,7 +10,7 @@ # - Interim look for Efficacy: # Pr( success at final ) > 80% or P(success at final) > phiU # - Interim look for Futility: -# Pr( failure at final ) < 20% or P(success at final) < phiL +# Pr( success at final ) < 20% or P(success at final) < phiL # We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. set.seed(20) @@ -41,10 +41,14 @@ result$oc # Desired difference to Standard of Care for Efficacy and Futility is 10% and -10% respectively. # Grey zone occurs due to different posterior probability distribution in the Efficacy and Futility rules. # Delta calculation is absolute case. The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate + deltaE > 25% ) > 60% or P(response rate + deltaE > p0) > tT -# - Final look for Futility: Pr( response rate + deltaF < 25% ) < 60% or P(response rate + deltaF > p0) < tT -# - Interim look for Efficacy: Pr( success at final ) > 80% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) < 20% or P(success at final) < phiL +# - Final look for Efficacy: Pr( response rate + deltaE > 25% ) > 60% or +# P(response rate + deltaE > p0) > tT +# - Final look for Futility: Pr( response rate + deltaF < 25% ) < 60% or +# P(response rate + deltaF > p0) < tT +# - Interim look for Efficacy: Pr( success at final ) > 80% or +# P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) < 20% or +# P(success at final) < phiL # We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. # set.seed(20) @@ -111,10 +115,10 @@ result$oc # True response rate or truep of the treatment group = 40% # Desired difference to Standard of Care for Efficacy and Futility = 50% # Delta calculation is relative case. The following are the Final Stop rules respectively : -# - Final look for Efficacy: P( P_S + (1-P_S)*deltaE > 25% ) > 60% or P( P_S + (1-P_S)*deltaE > p0) > tT -# - Final look for Futility: P( P_S + (1-P_S)*deltaEF < 25% ) < 60% or P( P_S + (1-P_S)*deltaF > p0) < tT -# - Interim look for Efficacy: P( success at final ) > 80% or P(success at final) > phiU -# - Interim look for Futility: P( failure at final ) < 20% or P(success at final) < phiL +# - Final look for Efficacy: P( P_S + (1-P_S)*deltaE > 25% ) > 60% +# - Final look for Futility: P( P_S + (1-P_S)*deltaEF < 25% ) < 60% +# - Interim look for Efficacy: P( success at final ) > 80% +# - Interim look for Futility: P( failure at final ) < 20% # We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. set.seed(20) diff --git a/examples/plotBounds.R b/examples/plotBounds.R index c28479ea..42c34b05 100644 --- a/examples/plotBounds.R +++ b/examples/plotBounds.R @@ -1,9 +1 @@ # examples -plotBounds(boundsPredprob( - nvec = c(10, 20, 30, 40), p = 0.20, tT = 0.80, - phiL = 0.10, phiU = 0.90, a = 1, b = 1 -), yt = "x") -plotBounds(boundsPredprob( - nvec = c(10, 20, 30, 40), p = 0.20, tT = 0.80, - phiL = 0.10, phiU = 0.90, a = 1, b = 1 -), yt = "p") diff --git a/man/ocPredprobDist.Rd b/man/ocPredprobDist.Rd index 3a570cfa..eeb7de5f 100644 --- a/man/ocPredprobDist.Rd +++ b/man/ocPredprobDist.Rd @@ -144,7 +144,7 @@ seen in the evaluation for the final futility look in \code{\link[=ocPredprobDis # - Interim look for Efficacy: # Pr( success at final ) > 80\% or P(success at final) > phiU # - Interim look for Futility: -# Pr( failure at final ) < 20\% or P(success at final) < phiL +# Pr( success at final ) < 20\% or P(success at final) < phiL # We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. set.seed(20) @@ -175,10 +175,14 @@ result$oc # Desired difference to Standard of Care for Efficacy and Futility is 10\% and -10\% respectively. # Grey zone occurs due to different posterior probability distribution in the Efficacy and Futility rules. # Delta calculation is absolute case. The following are the Final Stop rules respectively : -# - Final look for Efficacy: Pr( response rate + deltaE > 25\% ) > 60\% or P(response rate + deltaE > p0) > tT -# - Final look for Futility: Pr( response rate + deltaF < 25\% ) < 60\% or P(response rate + deltaF > p0) < tT -# - Interim look for Efficacy: Pr( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: Pr( failure at final ) < 20\% or P(success at final) < phiL +# - Final look for Efficacy: Pr( response rate + deltaE > 25\% ) > 60\% or +# P(response rate + deltaE > p0) > tT +# - Final look for Futility: Pr( response rate + deltaF < 25\% ) < 60\% or +# P(response rate + deltaF > p0) < tT +# - Interim look for Efficacy: Pr( success at final ) > 80\% or +# P(success at final) > phiU +# - Interim look for Futility: Pr( failure at final ) < 20\% or +# P(success at final) < phiL # We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. # set.seed(20) @@ -245,10 +249,14 @@ result$oc # True response rate or truep of the treatment group = 40\% # Desired difference to Standard of Care for Efficacy and Futility = 50\% # Delta calculation is relative case. The following are the Final Stop rules respectively : -# - Final look for Efficacy: P( P_S + (1-P_S)*deltaE > 25\% ) > 60\% or P( P_S + (1-P_S)*deltaE > p0) > tT -# - Final look for Futility: P( P_S + (1-P_S)*deltaEF < 25\% ) < 60\% or P( P_S + (1-P_S)*deltaF > p0) < tT -# - Interim look for Efficacy: P( success at final ) > 80\% or P(success at final) > phiU -# - Interim look for Futility: P( failure at final ) < 20\% or P(success at final) < phiL +# - Final look for Efficacy: P( P_S + (1-P_S)*deltaE > 25\% ) > 60\% or +# P( P_S + (1-P_S)*deltaE > p0) > tT +# - Final look for Futility: P( P_S + (1-P_S)*deltaEF < 25\% ) < 60\% or +# P( P_S + (1-P_S)*deltaF > p0) < tT +# - Interim look for Efficacy: P( success at final ) > 80\% or +# P(success at final) > phiU +# - Interim look for Futility: P( failure at final ) < 20\% or +# P(success at final) < phiL # We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. set.seed(20) diff --git a/man/plotBounds.Rd b/man/plotBounds.Rd index 0ee0034d..1cd568db 100644 --- a/man/plotBounds.Rd +++ b/man/plotBounds.Rd @@ -56,13 +56,5 @@ and \code{\link{boundsPostprob}} } \examples{ # examples -plotBounds(boundsPredprob( - nvec = c(10, 20, 30, 40), p = 0.20, tT = 0.80, - phiL = 0.10, phiU = 0.90, a = 1, b = 1 -), yt = "x") -plotBounds(boundsPredprob( - nvec = c(10, 20, 30, 40), p = 0.20, tT = 0.80, - phiL = 0.10, phiU = 0.90, a = 1, b = 1 -), yt = "p") } \keyword{graphics} From e5850930bcef05d0854c7ce51d03073f75a12343 Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:19:53 +0000 Subject: [PATCH 16/19] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/ocPredprobDist.Rd | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/man/ocPredprobDist.Rd b/man/ocPredprobDist.Rd index eeb7de5f..99accac9 100644 --- a/man/ocPredprobDist.Rd +++ b/man/ocPredprobDist.Rd @@ -249,14 +249,10 @@ result$oc # True response rate or truep of the treatment group = 40\% # Desired difference to Standard of Care for Efficacy and Futility = 50\% # Delta calculation is relative case. The following are the Final Stop rules respectively : -# - Final look for Efficacy: P( P_S + (1-P_S)*deltaE > 25\% ) > 60\% or -# P( P_S + (1-P_S)*deltaE > p0) > tT -# - Final look for Futility: P( P_S + (1-P_S)*deltaEF < 25\% ) < 60\% or -# P( P_S + (1-P_S)*deltaF > p0) < tT -# - Interim look for Efficacy: P( success at final ) > 80\% or -# P(success at final) > phiU -# - Interim look for Futility: P( failure at final ) < 20\% or -# P(success at final) < phiL +# - Final look for Efficacy: P( P_S + (1-P_S)*deltaE > 25\% ) > 60\% +# - Final look for Futility: P( P_S + (1-P_S)*deltaEF < 25\% ) < 60\% +# - Interim look for Efficacy: P( success at final ) > 80\% +# - Interim look for Futility: P( failure at final ) < 20\% # We assume a prior of treatment arm parE = Beta(1,1), unless otherwise indicated. set.seed(20) From eba4d49d78b0ab8d9e766c8a0a00c1a442c74097 Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Wed, 2 Oct 2024 18:38:39 +0200 Subject: [PATCH 17/19] clean From e4864b52e363991d9cbf3b3ac9e92be4fc40c1ec Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Thu, 10 Oct 2024 04:08:48 +0200 Subject: [PATCH 18/19] test case with pred prob passes with missing weights argument --- R/boundsPredprob.R | 3 +-- tests/testthat/test-boundsPredprob.R | 37 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/R/boundsPredprob.R b/R/boundsPredprob.R index 27e916b9..a92e6726 100644 --- a/R/boundsPredprob.R +++ b/R/boundsPredprob.R @@ -42,7 +42,6 @@ boundsPredprob <- function(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE = z <- matrix(NA, length(looks), length(znames)) dimnames(z) <- list(looks, znames) k <- 0 - parE <- t(parE) if (missing(weights)) { weights <- rep(1, nrow(parE)) } @@ -53,7 +52,7 @@ boundsPredprob <- function(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE = xL <- NA xU <- NA for (x in 0:n) { - predprob <- predprob(x, n, Nmax, p0, tT, parE = parE)$result + predprob <- predprob(x = x, n = n, Nmax = max(looks), p = p0, thetaT = tT, parE = parE, weights = weights)$result if (predprob <= phiL) { # Futility look, Rule Pr(Pr(P > p0 | x, Y, a, b) >= tT | x) =< phiL xL <- x predL <- predprob diff --git a/tests/testthat/test-boundsPredprob.R b/tests/testthat/test-boundsPredprob.R index ae62fee8..e6a9601f 100644 --- a/tests/testthat/test-boundsPredprob.R +++ b/tests/testthat/test-boundsPredprob.R @@ -67,3 +67,40 @@ test_that("boundsPredprob of beta mixture gives correct result", { expect_equal(result$postU, c(0.9883, 0.9727, 0.8919)) expect_equal(result$LciU, c(0.3413, 0.2437, 0.1773)) }) + +test_that("boundsPredprob of beta mixture gives correct result", { + result <- boundsPredprob( + looks = c(7, 15, 20), + p0 = 0.2, + tT = 0.80, + phiL = 0.10, + phiU = 0.90, + parE = rbind(c(1, 1), c(3, 10)), + weights = c(0.2, 0.8) + ) + expected <- data.frame( + list( + looks = c(7, 15, 20), + xL = c(1, 3, 6), + pL = c(0.1429, 0.2000, 0.3000), + predL = c(0.0446, 0.0121, 0.0000), + postL = c(0.2407, 0.3818, 0.7734), + UciL = c(0.5207, 0.4398, 0.5078), + xU = c(5, 7, 7), + pU = c(0.7143, 0.4667, 0.3500), + predU = c(0.9843, 1.0000, 1.0000), + postU = c(0.9883, 0.9727, 0.8919), + LciU = c(0.3413, 0.2437, 0.1773) + ) + ) + expect_equal(result$xL, c(1, 3, 6)) + expect_equal(result$pL, c(0.1429, 0.2000, 0.3000)) + expect_equal(result$predL, c(0.0446, 0.0121, 0.0000)) + expect_equal(result$postL, c(0.2407, 0.3818, 0.7734)) + expect_equal(result$UciL, c(0.5207, 0.4398, 0.5078)) + expect_equal(result$xU, c(5, 7, 7)) + expect_equal(result$pU, c(0.7143, 0.4667, 0.3500)) + expect_equal(result$predU, c(0.9843, 1.0000, 1.0000)) + expect_equal(result$postU, c(0.9883, 0.9727, 0.8919)) + expect_equal(result$LciU, c(0.3413, 0.2437, 0.1773)) +}) From 945a2b974d94600b18cfbd29699a68724b2ea3ff Mon Sep 17 00:00:00 2001 From: Audrey Yeo Date: Thu, 10 Oct 2024 13:10:09 +0200 Subject: [PATCH 19/19] clean --- R/boundsPredprob.R | 4 - examples/boundsPredprob.R | 2 +- man/boundsPredprob.Rd | 2 +- tests/testthat/test-boundsPredprob.R | 117 +++++++++++++-------------- 4 files changed, 58 insertions(+), 67 deletions(-) diff --git a/R/boundsPredprob.R b/R/boundsPredprob.R index a92e6726..71f02452 100644 --- a/R/boundsPredprob.R +++ b/R/boundsPredprob.R @@ -42,10 +42,6 @@ boundsPredprob <- function(looks, Nmax = max(looks), p0, tT, phiL, phiU, parE = z <- matrix(NA, length(looks), length(znames)) dimnames(z) <- list(looks, znames) k <- 0 - if (missing(weights)) { - weights <- rep(1, nrow(parE)) - } - assert_numeric(weights, min.len = 0, len = nrow(par), finite = TRUE) for (n in looks) { k <- k + 1 # initialize so will return NA if 0 or n in "continue" region diff --git a/examples/boundsPredprob.R b/examples/boundsPredprob.R index 1150fd9a..934c0064 100644 --- a/examples/boundsPredprob.R +++ b/examples/boundsPredprob.R @@ -28,6 +28,6 @@ boundsPredprob( tT = 0.80, phiL = 0.60, phiU = 0.90, - parE = rbind(c(1, 1), c(3, 10)), + parE = cbind(c(1, 1), c(3, 10)), weights = c(0.2, 0.8) ) diff --git a/man/boundsPredprob.Rd b/man/boundsPredprob.Rd index 7c43eca2..aba286bc 100644 --- a/man/boundsPredprob.Rd +++ b/man/boundsPredprob.Rd @@ -90,7 +90,7 @@ boundsPredprob( tT = 0.80, phiL = 0.60, phiU = 0.90, - parE = rbind(c(1, 1), c(3, 10)), + parE = cbind(c(1, 1), c(3, 10)), weights = c(0.2, 0.8) ) } diff --git a/tests/testthat/test-boundsPredprob.R b/tests/testthat/test-boundsPredprob.R index e6a9601f..7144dc2c 100644 --- a/tests/testthat/test-boundsPredprob.R +++ b/tests/testthat/test-boundsPredprob.R @@ -1,5 +1,14 @@ -# boundsPostProb ---- -test_that("boundsPredprob gives correct result", { +# boundsPredProb ---- +test_that("boundsPredprob gives correct result and when default weight is not assigned", { + result_weights <- boundsPredprob( + looks = c(10, 20, 30, 40), + p0 = 0.2, + tT = 0.80, + phiL = 0.10, + phiU = 0.90, + parE = c(1, 1), + weights = 1 + ) result <- boundsPredprob( looks = c(10, 20, 30, 40), p0 = 0.2, @@ -21,6 +30,7 @@ test_that("boundsPredprob gives correct result", { LciU = c(0.15, 0.1773, 0.1663, 0.1424) ) ) + expect_equal(result_weights, result) expect_equal(result$xL, c(0, 2, 5, 9)) expect_equal(result$pL, c(0, 0.1, 0.1667, 0.225)) expect_equal(result$postL, c(0.0859, 0.1787, 0.3931, 0.704)) @@ -31,76 +41,61 @@ test_that("boundsPredprob gives correct result", { expect_equal(result$LciU, c(0.15, 0.1773, 0.1663, 0.1424)) }) -test_that("boundsPredprob of beta mixture gives correct result", { +test_that("boundsPredprob with Beta Mixture Priors give correct results with predprob", { result <- boundsPredprob( - looks = c(7, 15, 20), - p0 = 0.2, + looks = c(10, 20), + p0 = 0.20, tT = 0.80, phiL = 0.10, phiU = 0.90, - parE = rbind(c(1, 1), c(3, 10)), + parE = cbind(c(1, 1), c(3, 10)), weights = c(0.2, 0.8) ) - expected <- data.frame( - list( - looks = c(7, 15, 20), - xL = c(1, 3, 6), - pL = c(0.1429, 0.2000, 0.3000), - predL = c(0.0446, 0.0121, 0.0000), - postL = c(0.2407, 0.3818, 0.7734), - UciL = c(0.5207, 0.4398, 0.5078), - xU = c(5, 7, 7), - pU = c(0.7143, 0.4667, 0.3500), - predU = c(0.9843, 1.0000, 1.0000), - postU = c(0.9883, 0.9727, 0.8919), - LciU = c(0.3413, 0.2437, 0.1773) - ) + result_predprob_lower <- predprob( + x = 2, + n = 10, + p = 0.20, + Nmax = 20, + thetaT = 0.80, + parE = cbind(c(1, 1), c(3, 10)), + weights = c(0.2, 0.8) ) - expect_equal(result$xL, c(1, 3, 6)) - expect_equal(result$pL, c(0.1429, 0.2000, 0.3000)) - expect_equal(result$predL, c(0.0446, 0.0121, 0.0000)) - expect_equal(result$postL, c(0.2407, 0.3818, 0.7734)) - expect_equal(result$UciL, c(0.5207, 0.4398, 0.5078)) - expect_equal(result$xU, c(5, 7, 7)) - expect_equal(result$pU, c(0.7143, 0.4667, 0.3500)) - expect_equal(result$predU, c(0.9843, 1.0000, 1.0000)) - expect_equal(result$postU, c(0.9883, 0.9727, 0.8919)) - expect_equal(result$LciU, c(0.3413, 0.2437, 0.1773)) -}) - -test_that("boundsPredprob of beta mixture gives correct result", { - result <- boundsPredprob( - looks = c(7, 15, 20), - p0 = 0.2, - tT = 0.80, - phiL = 0.10, - phiU = 0.90, - parE = rbind(c(1, 1), c(3, 10)), + result_predprob_upper <- predprob( + x = 6, + n = 10, + p = 0.20, + Nmax = 20, + thetaT = 0.80, + parE = cbind(c(1, 1), c(3, 10)), weights = c(0.2, 0.8) ) expected <- data.frame( list( - looks = c(7, 15, 20), - xL = c(1, 3, 6), - pL = c(0.1429, 0.2000, 0.3000), - predL = c(0.0446, 0.0121, 0.0000), - postL = c(0.2407, 0.3818, 0.7734), - UciL = c(0.5207, 0.4398, 0.5078), - xU = c(5, 7, 7), - pU = c(0.7143, 0.4667, 0.3500), - predU = c(0.9843, 1.0000, 1.0000), - postU = c(0.9883, 0.9727, 0.8919), - LciU = c(0.3413, 0.2437, 0.1773) + looks = c(10, 20), + xL = c(2, 6), + pL = c(0.2, 0.3), + predL = c(0.0409, 0), + postL = c(0.367, 0.7734), + UciL = c(0.5069, 0.5078), + xU = c(6, 7), + pU = c(0.6, 0.35), + predU = c(0.9859, 1), + postU = c(0.9875, 0.8919), + LciU = c(0.3035, 0.1773) ) ) - expect_equal(result$xL, c(1, 3, 6)) - expect_equal(result$pL, c(0.1429, 0.2000, 0.3000)) - expect_equal(result$predL, c(0.0446, 0.0121, 0.0000)) - expect_equal(result$postL, c(0.2407, 0.3818, 0.7734)) - expect_equal(result$UciL, c(0.5207, 0.4398, 0.5078)) - expect_equal(result$xU, c(5, 7, 7)) - expect_equal(result$pU, c(0.7143, 0.4667, 0.3500)) - expect_equal(result$predU, c(0.9843, 1.0000, 1.0000)) - expect_equal(result$postU, c(0.9883, 0.9727, 0.8919)) - expect_equal(result$LciU, c(0.3413, 0.2437, 0.1773)) + expect_equal(result$xL[1], 2) + expect_equal(result$predL[1], result_predprob_lower$result, tolerance = 1e-3) + expect_equal(result$xL[2], 6) + expect_equal(result$predU[1], result_predprob_upper$result, tolerance = 1e-4) + expect_equal(result$xL, c(2, 6)) + expect_equal(result$pL, c(0.2, 0.3)) + expect_equal(result$predL, c(0.0409, 0)) + expect_equal(result$postL, c(0.367, 0.7734)) + expect_equal(result$UciL, c(0.5069, 0.5078)) + expect_equal(result$xU, c(6, 7)) + expect_equal(result$pU, c(0.6, 0.35)) + expect_equal(result$predU, c(0.9859, 1)) + expect_equal(result$postU, c(0.9875, 0.8919)) + expect_equal(result$LciU, c(0.3035, 0.1773)) })