Title: | Group Sequential Design Class for Clinical Trials |
---|---|
Description: | S4 class object for creating and managing group sequential designs. It calculates the efficacy and futility boundaries at each look. It allows modifying the design and tracking the design update history. |
Authors: | David A Schoenfeld and Hui Zheng |
Maintainer: | Hui Zheng <[email protected]> |
License: | MIT + file LICENSE |
Version: | 2.5 |
Built: | 2024-10-15 06:19:41 UTC |
Source: | CRAN |
a package for creating, monitoring and modifying a group sequential design
The DESCRIPTION file: DESCRIPTION
David A Schoenfeld, PhD and Hui Zheng, PhD
Proschan, MA, Lan, KKG, Wittes, JT, Statistical Monitoring of Clinical Trials: A Unified Approach, Springer, 2006
Schoenfeld DA, "A Simple Algorithm for Designing Group Sequential Clinical Trials", Biometrics. 2001 Sep;57(3):972-4.
design1<-sequential.design() design1<-calcBoundaries(design1) printDesign(design1) summaryDesign(design1)
design1<-sequential.design() design1<-calcBoundaries(design1) printDesign(design1) summaryDesign(design1)
Calculates the upper boundaries for efficacy at each look time
alphaspend(levels, t, int = rep(500, length(t)), tol = 0.005)
alphaspend(levels, t, int = rep(500, length(t)), tol = 0.005)
levels |
The cumulative alpha spending at each look time |
t |
Normalized look times |
int |
The number of intervals the solution space is partitioned into |
tol |
Tolerance of the solution using uniroot |
numeric
f<- function(t) 0.025*t^4 t<-c(0.33,0.67,1) cum_probs<-f(t) alphaspend(levels=cum_probs,t,int=rep(500, length(t)),tol=0.005)
f<- function(t) 0.025*t^4 t<-c(0.33,0.67,1) cum_probs<-f(t) alphaspend(levels=cum_probs,t,int=rep(500, length(t)),tol=0.005)
The default alpha spending function
alphaspendf(t)
alphaspendf(t)
t |
The normalized look times |
numeric
t<-c(0.33,0.67,1) alphas<-alphaspendf(t) ## The function is currently defined as function (t) 0.025 * t^4
t<-c(0.33,0.67,1) alphas<-alphaspendf(t) ## The function is currently defined as function (t) 0.025 * t^4
Calculates the lower boundaries for futility at each look
betaspend(levels, upperboundary, t, int = rep(500, length(t)), noncent, tol = 0.005)
betaspend(levels, upperboundary, t, int = rep(500, length(t)), noncent, tol = 0.005)
levels |
The cumulative beta spending at each look time |
upperboundary |
The upper efficacy boundaries at each look |
t |
Normalized look times |
int |
The numbers of intervals the solution space is partitioned into |
noncent |
The noncentrality parameter |
tol |
Tolerance of the solution using uniroot |
numeric
f<- function(t) 0.025*t^4 g<- function(t) 0.15*t^3 t<-c(0.33,0.67,1) cum_alphas<-f(t) cum_betas<-g(t) noncent<-qnorm(0.975)+qnorm(0.85) upper_boundaries<-alphaspend(cum_alphas,t,int=rep(500, length(t)),tol=0.005) lower_boundaries<-betaspend(cum_betas, upper_boundaries, t, int = rep(500,3), noncent, tol = 0.005)
f<- function(t) 0.025*t^4 g<- function(t) 0.15*t^3 t<-c(0.33,0.67,1) cum_alphas<-f(t) cum_betas<-g(t) noncent<-qnorm(0.975)+qnorm(0.85) upper_boundaries<-alphaspend(cum_alphas,t,int=rep(500, length(t)),tol=0.005) lower_boundaries<-betaspend(cum_betas, upper_boundaries, t, int = rep(500,3), noncent, tol = 0.005)
The default beta spending function
betaspendf(t)
betaspendf(t)
t |
The normalized look times |
numeric
t<-c(0.33,0.67,1) betas<-betaspendf(t) ## The function is currently defined as function (t) 0.15 * t^3
t<-c(0.33,0.67,1) betas<-betaspendf(t) ## The function is currently defined as function (t) 0.15 * t^3
Calculates the efficacy and futility boundaries. This only needs to be done once for a new design.
calcBoundaries(theObject)
calcBoundaries(theObject)
theObject |
The sequential design object |
numeric
design1<-sequential.design() design1<-calcBoundaries(design1) [email protected] [email protected]
design1<-sequential.design() design1<-calcBoundaries(design1) design1@lower.boundary design1@upper.boundary
Calculates the probability to declare efficacy at the end of study given the Z value at the current look
curtail(lower.boundary,upper.boundary,look,t,noncen,current=lower.boundary[look])
curtail(lower.boundary,upper.boundary,look,t,noncen,current=lower.boundary[look])
lower.boundary |
lower boundaries |
upper.boundary |
upper boundaries |
look |
current look number |
t |
time of looks |
noncen |
noncentrality parameter |
current |
current Z statistic |
numeric
t<-c(0.33,0.67,1) f<- function(t) 0.025*t^4 g<-function(t) 0.20*t^3 a<-f(t) b<-g(t) noncen<-pnorm(0.975)+pnorm(0.8) curtail(b,a,1,t,noncen)
t<-c(0.33,0.67,1) f<- function(t) 0.025*t^4 g<-function(t) 0.20*t^3 a<-f(t) b<-g(t) noncen<-pnorm(0.975)+pnorm(0.8) curtail(b,a,1,t,noncen)
calculates the probability for efficacy given the Z value
curtailDesign(theObject, current0)
curtailDesign(theObject, current0)
theObject |
The sequential design object |
current0 |
The current Z value |
numeric
design1<-sequential.design() design1<-calcBoundaries(design1) design1<-setCurrentLook(design1,1) prob1<-curtailDesign(design1,1.5)
design1<-sequential.design() design1<-calcBoundaries(design1) design1<-setCurrentLook(design1,1) prob1<-curtailDesign(design1,1.5)
Calculates the cumulative probabilities to declare efficacy and futility under the null hypothesis and the alternative hypothesis. It also returns the p-values for declaring efficacy and futility.
getProbabilities(theObject)
getProbabilities(theObject)
theObject |
The sequential design object |
numeric
design1<-sequential.design() probs<-getProbabilities(design1)
design1<-sequential.design() probs<-getProbabilities(design1)
Plots the efficacy and futility boundaries
plotBoundaries(theObject)
plotBoundaries(theObject)
theObject |
The sequential design object |
design1<-sequential.design() design1<-calcBoundaries(design1) plotBoundaries(design1)
design1<-sequential.design() design1<-calcBoundaries(design1) plotBoundaries(design1)
Displays the look times, the base alpha and beta spending functions, and the noncentrality parameter
## S4 method for signature 'sequential.design' printDesign(theObject)
## S4 method for signature 'sequential.design' printDesign(theObject)
theObject |
An object of class |
Prints the details to the console.
design1<-sequential.design() design1<-calcBoundaries(design1) design1<-setAlphaspendfString(design1,"0.025*t^4") design1<-setBetaspendfString(design1,"0.15*t^3") printDesign(design1)
design1<-sequential.design() design1<-calcBoundaries(design1) design1<-setAlphaspendfString(design1,"0.025*t^4") design1<-setBetaspendfString(design1,"0.15*t^3") printDesign(design1)
Finds the probability that a sequence of standard normal random variables derived from a normal stochastic process with independent increments will cross a lower and and upper boundary.
seqmon(a, b, t, int = rep(500, length(t)))
seqmon(a, b, t, int = rep(500, length(t)))
a |
Lower boundary as a numeric vector of length |
b |
Upper boundary as a numeric vector of length |
t |
Information times as a numeric vector of length |
int |
number of intervals that the Z-space is partitioned into for calculation purposes, increasing this will improve accuracy, this is also a numeric vector of length |
Produces a numeric vector of length the first
components are the probability that the
will be less than
for some
and be less than
for all
. The second
components are the probability that the
will be greater than
for some
and be greater than
for all
.
Note that the last probability in the sequence is the overall significance level of a sequential design that uses a
and b
as upper and lower boundaries. To get power you subtract the from
a
and b
where is the mean of
under the alternative hypothesis.
Schoenfeld, David A. "A simple algorithm for designing group sequential clinical trials." Biometrics 57.3 (2001): 972-974.
seqmon(a=c(0,0,0), b=c(qnorm(1-0.005),qnorm(1-0.005),2.025), t=c(.33,.66,1), int = rep(500, 3)) t=c(.33,.66,1) u=(qnorm(.8)+qnorm(1-0.025)) seqmon(a=c(0,0,0)-u*sqrt(t), b=c(qnorm(1-0.005),qnorm(1-0.005),2.025)-u*sqrt(t), t=c(.33,.66,1), int = rep(500, 3))
seqmon(a=c(0,0,0), b=c(qnorm(1-0.005),qnorm(1-0.005),2.025), t=c(.33,.66,1), int = rep(500, 3)) t=c(.33,.66,1) u=(qnorm(.8)+qnorm(1-0.025)) seqmon(a=c(0,0,0)-u*sqrt(t), b=c(qnorm(1-0.005),qnorm(1-0.005),2.025)-u*sqrt(t), t=c(.33,.66,1), int = rep(500, 3))
The S4 sequential design class
sequential.design(...)
sequential.design(...)
... |
Additional arguments passed to the methods. |
The sequential design class stores the information of a sequential design, including revision history.
an object of the class "sequential.design"
David A. Schoendfeld, PhD and Hui Zheng, PhD
Proschan, MA; Lan, KKG; Wittes JT,"Statistical Monitoring of Clinical Trials: A Unified Approach", Chapter 6, Springer 2006.
Schoenfeld DA, "A Simple Algorithm for Designing Group Sequential Clinical Trials", Biometrics. 2001 Sep;57(3):972-4.
design1<-sequential.design()
design1<-sequential.design()
"sequential.design"
The sequential design class
Objects can be created by calls of the form sequential.design(...)
.
lower.boundary
:Object of class "numeric"
upper.boundary
:Object of class "numeric"
times
:Object of class "numeric"
noncentrality
:Object of class "numeric"
base.alpha.spend
:Object of class "function"
base.beta.spend
:Object of class "function"
base.alpha.spend.string
:Object of class "character"
base.beta.spend.string
:Object of class "character"
current.look
:Object of class "numeric"
current.alpha.spend
:Object of class "numeric"
current.beta.spend
:Object of class "numeric"
times.history
:Object of class "numeric"
alpha.spent.history
:Object of class "numeric"
beta.spent.history
:Object of class "numeric"
alpha.func.history
:Object of class "numeric"
beta.func.history
:Object of class "numeric"
date.stamp
:Object of class "POSIXct"
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
signature(theObject = "sequential.design")
: ...
showClass("sequential.design")
showClass("sequential.design")
Sets the expression of the base alpha spending function as a string. This function is only used if one needs to display the base alpha spending function as a string. This function DOES NOT update the base alpha spending function. One can use setBaseAlphaspendf() to change the base alpha spending function. The spending functions and their string expressions should be defined only once per object. They should not be updated during any interim update to the design.
setAlphaspendfString(theObject, string0)
setAlphaspendfString(theObject, string0)
theObject |
The sequential design object |
string0 |
The string of the expression of the base alpha spending function. Its argument need to be 't'. |
an object of class "sequential.design"
design1<-sequential.design() design1<-setAlphaspendfString(design1,'0.025*t^4')
design1<-sequential.design() design1<-setAlphaspendfString(design1,'0.025*t^4')
Sets the base alpha spending function.
setBaseAlphaspendf(theObject, funct0)
setBaseAlphaspendf(theObject, funct0)
theObject |
The sequential design object |
funct0 |
The base alpha spending function. It needs to be defined before this method is called. |
an object of class "sequential.design"
design1<-sequential.design() f1<-function (t) 0.025*t^3.5 design1<-setBaseAlphaspendf(design1,f1)
design1<-sequential.design() f1<-function (t) 0.025*t^3.5 design1<-setBaseAlphaspendf(design1,f1)
Sets the base beta spending function.
setBaseBetaspendf(theObject, funct0)
setBaseBetaspendf(theObject, funct0)
theObject |
The sequential design object |
funct0 |
The base beta spending function. It needs to be defined before this method is called. |
an object of class "sequential.design"
design1<-sequential.design() f2<-function (t) 0.15*t^2.5 design1<-setBaseBetaspendf(design1,f2)
design1<-sequential.design() f2<-function (t) 0.15*t^2.5 design1<-setBaseBetaspendf(design1,f2)
Sets the expression of the base beta spending function as a string. This function is only used if one needs to display the base beta spending function as a string. This function DOES NOT update the base beta spending function. One can use setBaseBetaspendf() to change the base beta spending function. The spending functions and their string expressions should be defined only once per object. They should not be updated during any interim update to the design.
setBetaspendfString(theObject, string0)
setBetaspendfString(theObject, string0)
theObject |
The sequential design object |
string0 |
The string of the expression of the base beta spending function. Its argument need to be 't'. |
an object of class "sequential.design"
design1<-sequential.design() design1<-setBetaspendfString(design1,'0.15*t^3.5')
design1<-sequential.design() design1<-setBetaspendfString(design1,'0.15*t^3.5')
Sets the current look number. The curent look is the one that last took place.
setCurrentLook(theObject, look0)
setCurrentLook(theObject, look0)
theObject |
The sequential design object |
look0 |
The curent look number |
The curent look is the one that last took place. One can only set the current look forward. If the new current look number attempted is less than the old current look number, no action will take place and the current look number will not be updated.
an object of class "sequential.design"
design1<-sequential.design() design1<-setCurrentLook(design1,2)
design1<-sequential.design() design1<-setCurrentLook(design1,2)
Sets the date stamp of the design object
setDatestamp(theObject, date0)
setDatestamp(theObject, date0)
theObject |
The sequential design object |
date0 |
The date value. |
an object of class "sequential.design"
design1<-sequential.design() design1<-setDatestamp(design1,as.POSIXct("2018-10-30"))
design1<-sequential.design() design1<-setDatestamp(design1,as.POSIXct("2018-10-30"))
Sets the noncentrality parameter.
setNoncentrality(theObject, noncent)
setNoncentrality(theObject, noncent)
theObject |
The sequential design object |
noncent |
The noncentrality parameter |
The noncentrality paraeter is the expected drift at the end of the study. For example, if the study has a power of 80% using a one sided Z-test with 2.5% type 1 error, the noncentrality parameter is q(0.975)+q(0.8), where q() is the percentile function of the standard normal distribution.
an object of class "sequential.design"
design1<-sequential.design() noncent<-qnorm(0.975,0,1)+qnorm(0.8,0,1) design1<-setNoncentrality(design1,noncent)
design1<-sequential.design() noncent<-qnorm(0.975,0,1)+qnorm(0.8,0,1) design1<-setNoncentrality(design1,noncent)
Sets the look times. It is to be called only for the inital design, not for updating the design.
setTimes(theObject, time0)
setTimes(theObject, time0)
theObject |
The sequential design object |
time0 |
The look times. |
an object of class "sequential.design"
design1<-sequential.design() design1<-setTimes(design1,c(1,2,3))
design1<-sequential.design() design1<-setTimes(design1,c(1,2,3))
Shows the cumulative probability for efficacy and futility under the null and alternative hypotheses, the corresponding p-values, and the boundaries for Z at each look.
## S4 method for signature 'sequential.design' summaryDesign(theObject)
## S4 method for signature 'sequential.design' summaryDesign(theObject)
theObject |
An object of class |
Prints a summary matrix to the console.
design2 <- calcBoundaries(sequential.design()) # Summarize the design summaryDesign(design2)
design2 <- calcBoundaries(sequential.design()) # Summarize the design summaryDesign(design2)
Updates the design. This can be done in the process of the study, when the future look times need to be changed from those originally planned.
updateDesign(theObject, futureTimes)
updateDesign(theObject, futureTimes)
theObject |
The sequential design object |
futureTimes |
The future look times. |
The efficacy and futility boundaries will be updated according to the new future look times. If the new final look is before the planned final look, the efficacy and futility boundaries will be updated, but the alpha and beta spending functions need not be updated. If the new final look is after the planned final look, the efficacy and futility boundaries will be updated, as well as the alpha and beta spending functions. The details are given in Proschan, Lan, and Wittes(2006) and Schoenfeld (2001). No historical information such as the past look times, the past alpha and beta spent, or the baseline spending function is updated.
an object of class "sequential.design"
David A Schoenfeld, PhD and Hui Zheng, PhD
Proschan, MA; Lan, KKG; Wittes JT,"Statistical Monitoring of Clinical Trials: A Unified Approach", Chapter 6, Springer 2006.
Schoenfeld DA, "A Simple Algorithm for Designing Group Sequential Clinical Trials", Biometrics. 2001 Sep;57(3):972-4.
design1<-sequential.design() design1<-setTimes(design1,c(1,2)) design1<-calcBoundaries(design1) design1<-setCurrentLook(design1,1) design2<-updateDesign(design1,c(3))
design1<-sequential.design() design1<-setTimes(design1,c(1,2)) design1<-calcBoundaries(design1) design1<-setCurrentLook(design1,1) design2<-updateDesign(design1,c(3))