Skip to contents

sequentialPValue computes a sequential p-value for a group sequential design using a spending function as described in Maurer and Bretz (2013) and previously defined by Liu and Anderson (2008). It is the minimum of repeated p-values computed at each analysis (Jennison and Turnbull, 2000). This is particularly useful for multiplicity methods such as the graphical method for group sequential designs where sequential p-values for multiple hypotheses can be used as nominal p-values to plug into a multiplicity graph. A sequential p-value is described as the minimum alpha level at which a one-sided group sequential bound would be rejected given interim and final observed results. It is meaningful for both one-sided designs and designs with non-binding futility bounds (test.type 1, 4, 6), but not for 2-sided designs with binding futility bounds (test.type 2, 3 or 5). Mild restrictions are required on spending functions used, but these are satisfied for commonly used spending functions such as the Lan-DeMets spending function approximating an O'Brien-Fleming bound or a Hwang-Shih-DeCani spending function; see Maurer and Bretz (2013).

Usage

sequentialPValue(
  gsD = gsDesign(),
  n.I = NULL,
  Z = NULL,
  usTime = NULL,
  interval = c(1e-05, 0.9999)
)

Arguments

gsD

Group sequential design generated by gsDesign or gsSurv.

n.I

Event counts (for time-to-event outcomes) or sample size (for most other designs); numeric vector with increasing, positive values with at most one value greater than or equal to largest value in gsD$n.I; NOTE: if NULL, planned n.I will be used (gsD$n.I).

Z

Z-value tests corresponding to analyses in n.I; positive values indicate a positive finding; must have the same length as n.I.

usTime

Spending time for upper bound at specified analyses; specify default: NULL if this is to be based on information fraction; if not NULL, must have the same length as n.I; increasing positive values with at most 1 greater than or equal to 1.

interval

Interval for search to derive p-value; Default: c(1e-05, 0.9999). Lower end of interval must be >0 and upper end must be < 1. The primary reason to not use the defaults would likely be if a test were vs a Type I error <0.0001.

Value

Sequential p-value (single numeric one-sided p-value between 0 and 1). Note that if the sequential p-value is less than the lower end of the input interval, the lower of interval will be returned. Similarly, if the sequential p-value is greater than the upper end of the input interval, then the upper end of interval is returned.

Details

Solution is found with a search using uniroot. This finds the maximum alpha-level for which an efficacy bound is crossed, completely ignoring any futility bound.

References

Jennison C and Turnbull BW (2000), Group Sequential Methods with Applications to Clinical Trials. Boca Raton: Chapman and Hall.

Liu, Qing, and Keaven M. Anderson. "On adaptive extensions of group sequential trials for clinical investigations." Journal of the American Statistical Association 103.484 (2008): 1621-1630.

Maurer, Willi, and Frank Bretz. "Multiple testing in group sequential trials using graphical approaches." Statistics in Biopharmaceutical Research 5.4 (2013): 311-320.;

Author

Keaven Anderson

Examples


# Derive Group Sequential Design 
x <- gsSurv(k = 4, alpha = 0.025, beta = 0.1, timing = c(.5,.65,.8), sfu = sfLDOF,
            sfl = sfHSD, sflpar = 2, lambdaC = log(2)/6, hr = 0.6,
            eta = 0.01 , gamma = c(2.5,5,7.5,10), R = c( 2,2,2,6 ),
            T = 30 , minfup = 18)
x$n.I
#> [1] 109.2757 142.0585 174.8412 218.5515
# Analysis at IA2
sequentialPValue(gsD=x,n.I=c(100,160),Z=c(1.5,2))
#> [1] 0.05363369
# Use planned spending instead of information fraction; do final analysis
seqp <- sequentialPValue(gsD=x,n.I=c(100,160,190,230),Z=c(1.5,2,2.5,3),usTime=x$timing)
seqp
#> [1] 0.001452684
# Check bounds for updated design to verify at least one was crossed
xupdate <- gsDesign(maxn.IPlan=max(x$n.I),n.I=c(100,160,190,230),usTime=x$timing,
                    delta=x$delta,delta1=x$delta1,k=4,alpha=x$alpha,test.type=1,
                    sfu=x$upper$sf,sfupar=x$upper$param)
gsBoundSummary(xupdate,logdelta=TRUE,Nname="Events",deltaname="HR")
#>     Analysis              Value Efficacy
#>    IA 1: 46%                  Z   2.9626
#>  Events: 100        p (1-sided)   0.0015
#>                    ~HR at bound   0.5529
#>                P(Cross) if HR=1   0.0015
#>              P(Cross) if HR=0.6   0.3456
#>    IA 2: 73%                  Z   2.6020
#>  Events: 160        p (1-sided)   0.0046
#>                    ~HR at bound   0.6627
#>                P(Cross) if HR=1   0.0054
#>              P(Cross) if HR=0.6   0.7459
#>    IA 3: 87%                  Z   2.3051
#>  Events: 190        p (1-sided)   0.0106
#>                    ~HR at bound   0.7157
#>                P(Cross) if HR=1   0.0122
#>              P(Cross) if HR=0.6   0.8953
#>        Final                  Z   2.0241
#>  Events: 230        p (1-sided)   0.0215
#>                    ~HR at bound   0.7657
#>                P(Cross) if HR=1   0.0250
#>              P(Cross) if HR=0.6   0.9709
# Now update bound using sequential p-value as alpha level
xupdate <- gsDesign(maxn.IPlan=max(x$n.I),n.I=c(100,160,190,230),usTime=x$timing,
                    delta=x$delta,delta1=x$delta1,k=4,alpha=seqp,test.type=1,
                    sfu=x$upper$sf,sfupar=x$upper$param)
# Check that we are at bound for 1 (or more) analysis and did not exceed bound for others
gsBoundSummary(xupdate,logdelta=TRUE,Nname="Events",deltaname="HR")
#>     Analysis              Value Efficacy
#>    IA 1: 46%                  Z   4.3533
#>  Events: 100        p (1-sided)   0.0000
#>                    ~HR at bound   0.4187
#>                P(Cross) if HR=1   0.0000
#>              P(Cross) if HR=0.6   0.0369
#>    IA 2: 73%                  Z   3.7935
#>  Events: 160        p (1-sided)   0.0001
#>                    ~HR at bound   0.5489
#>                P(Cross) if HR=1   0.0001
#>              P(Cross) if HR=0.6   0.2930
#>    IA 3: 87%                  Z   3.3900
#>  Events: 190        p (1-sided)   0.0003
#>                    ~HR at bound   0.6115
#>                P(Cross) if HR=1   0.0004
#>              P(Cross) if HR=0.6   0.5612
#>        Final                  Z   3.0000
#>  Events: 230        p (1-sided)   0.0013
#>                    ~HR at bound   0.6733
#>                P(Cross) if HR=1   0.0015
#>              P(Cross) if HR=0.6   0.8161