## ###### ###### Title : Session3Code.q ###### Author : D. Gillen ###### Date : 08.14.2013 (UW Summer Institue in Biostatistics - Group Sequential Methods) ###### Description : Code for Session 3 (Group Sequential Study Design) ###### ## library( RCTdesign ) ## ##### ##### Hodgkin's lymphoma trial ##### ## ##### Specification of inital fixed sample design ## survFixed <- seqDesign( prob.model = "hazard", arms = 2, null.hypothesis = 1., alt.hypothesis = 0.67, ratio = c(1., 1.), nbr.analyses = 1, test.type = "less", power = 0.80, alpha = 0.025 ) survFixed ## ##### Estimation of accrual rate ## seqPHSubjects( survFixed, controlMedian=0.75, accrualTime=3, followupTime=1 ) ## ##### Determine expected number of events if accrual were restricted to 50/mth ## seqPHSubjects( survFixed, controlMedian = 0.75, accrualTime = 3, followupTime = 1, nEvents = 121 ) ## ##### Re-design trial with 121 maximal events ## survFixed.121 <- update( survFixed, sample.size=121, power="calculate" ) survFixed.121 ## ##### Compare power curve for re-designed trial ## seqPlotPower( survFixed, survFixed.121, dsnLbls=c("survFixed.196", "survFixed.121"), lwd=2 ) seqPlotPower( survFixed.121, reference=survFixed, dsnLbls=c("survFixed.196", "survFixed.121"), lwd=2 ) ## ## ##### ##### Definition of candidate group sequential designs for Hodgkin's trial ##### ## Fixed <- survFixed SymmOBF.2 <- update( Fixed, nbr.analyses=2, P=c(1,1), sample.size=196, power="calculate" ) SymmOBF.3 <- update( SymmOBF.2, nbr.analyses = 3, P=c(1,1) ) SymmOBF.4 <- update( SymmOBF.2, nbr.analyses = 4, P=c(1,1) ) SymmOBF.Power <- update( SymmOBF.4, power = 0.80 ) Futility.5 <- update( SymmOBF.4, P=c(1,.5) ) Futility.8 <- update( SymmOBF.4, P=c(1,.8) ) Futility.9 <- update( SymmOBF.4, P=c(1,.9) ) Eff11.Fut8 <- update( SymmOBF.4, P=c(1.1,.8) ) Eff11.Fut9 <- update( SymmOBF.4, P=c(1.1,.9) ) Fixed.Power <- update( SymmOBF.2, nbr.analyses=1, power=0.7767 ) ## ##### Determine approximate timing of interim analyses ## seqPHSubjects( SymmOBF.4, controlMedian=0.75, accrualTime=3, followupTime=1 ) ## ##### Stopping boundaries on various scales ## seqBoundary( SymmOBF.4, scale="X" ) seqBoundary( SymmOBF.4, scale="Z" ) 1-seqBoundary( SymmOBF.4, scale="P" ) seqBoundary( SymmOBF.4, scale="E" ) seqBoundary( SymmOBF.4, scale="E" )*.025 myscale <- seqScale("C", hypTheta = "design") seqBoundary(SymmOBF.4, myscale) myscale <- seqScale("C", hypTheta = "estimate") seqBoundary(SymmOBF.4, myscale) ## ##### Table HR, Zstat, and Fixed P boundaries ## bndStat <- round( cbind( seqBoundary( SymmOBF.4, scale="X" )[,1], seqBoundary( SymmOBF.4, scale="Z" )[,1], 1-seqBoundary( SymmOBF.4, scale="P" )[,1], seqBoundary( SymmOBF.4, scale="X" )[,4], seqBoundary( SymmOBF.4, scale="Z" )[,4], 1-seqBoundary( SymmOBF.4, scale="P" )[,4] ), 3 ) colnames( bndStat ) <- cbind( "lo.hr", "lo.ztat", "lo.pval", "up.hr", "up.zstat", "up.pval" ) bndStat ## ##### Plot stopping boundaries ## seqPlotBoundary( Fixed, Futility.8, Futility.9, SymmOBF.4, Eff11.Fut8, Eff11.Fut9, dsnLbls=c( "Fixed", "Futility.8", "Futility.9", "SymmOBF.4", "Eff11.Fut8", "Eff11.Fut9"), scale="X", lwd=2 ) ## ##### Plot power ## seqPlotPower( Fixed, Eff11.Fut8, Futility.8, Futility.9, SymmOBF.4, dsnLbls=c("Fixed", "Eff11.Fut8", "Futility.8", "Futility.9", "SymmOBF.4" ), lwd=2 ) seqPlotPower( Eff11.Fut8, Futility.8, Futility.9, SymmOBF.4, dsnLbls=c("Fixed", "Eff11.Fut8", "Futility.8", "Futility.9", "SymmOBF.4"), reference=Fixed, lwd=2 ) ## ##### Plot ASN ## seqPlotASN( Fixed, Eff11.Fut8, Futility.8, Futility.9, SymmOBF.4, dsnLbls=c("Fixed", "Eff11.Fut8", "Futility.8", "Futility.9", "SymmOBF.4"), lwd=2 ) ## ##### Operating characteristics ## seqOC( Eff11.Fut8, theta=seq(.6,1,by=.2) ) ## ##### Plot of stopping probabilities ## seqPlotStopProb( Eff11.Fut8 ) ## ##### Boundary Inference ## seqInference( Eff11.Fut8 ) seqPlotInference( Eff11.Fut8 ) ## ##### Further exploration of accrual patterns ## ################################################## ## ## Scenario: ## Accrual: Specify accrualSize (A), accrualTime (t_A), aShapeAccr ## -- aShapeAccr=10 and bShapeAccr=1 is faster accrual late ## -- aShapeAccr=1 and bShapeAccr=10 is slower accrual late ## -- studyTime is computed ## Event: eventQuantiles = .75 (median for exponential distribution) ## Dropout: none (default) ## ################################################## #draw the accrual distns b10.1 <- rbeta(1000, 10, 1) hist(3*b10.1) ## ##### Exploration of analysis timing by total number of subjects accrued ## ## Fast early accrual ## Eff11.Fut8Extd.early <- seqDesign(prob.model = "hazard", arms = 2, null.hypothesis = 1., alt.hypothesis = 0.67, ratio = c(1., 1.), nbr.analyses = 4, test.type = "less", alpha = 0.025, sample.size=196, power="calculate", P=c(1.1,.8), accrualTime=3, bShapeAccr=10, eventQuantiles=.75, nPtsSim=10000, seed=0) Eff11.Fut8Extd.early ## ## Slow early accrual ## Eff11.Fut8Extd.late <- seqDesign(prob.model = "hazard", arms = 2, null.hypothesis = 1., alt.hypothesis = 0.67, ratio = c(1., 1.), nbr.analyses = 4, test.type = "less", alpha = 0.025, sample.size=196, P=c(1.1,.8), accrualTime=3, aShapeAccr=10, eventQuantiles=.75, nPtsSim=10000, seed=0) Eff11.Fut8Extd.late ## ## Accrual plots for fixed number to be accrued ## ## Fast early accrual ## Eff11.Fut8Extd.early <- seqDesign(prob.model = "hazard", arms = 2, null.hypothesis = 1., alt.hypothesis = 0.67, ratio = c(1., 1.), nbr.analyses = 4, test.type = "less", alpha = 0.025, sample.size=263, power="calculate", P=c(1.1,.8), accrualSize=400, accrualTime=3, bShapeAccr=10, eventQuantiles=16/12, nPtsSim=10000, seed=0) Eff11.Fut8Extd.early seqPlotPHNSubjects(Eff11.Fut8Extd.early) ## ## Slow early accrual ## Eff11.Fut8Extd.late <- seqDesign(prob.model = "hazard", arms = 2, null.hypothesis = 1., alt.hypothesis = 0.67, ratio = c(1., 1.), nbr.analyses = 4, test.type = "less", alpha = 0.025, sample.size=263, power="calculate", P=c(1.1,.8), accrualSize=400, accrualTime=3, aShapeAccr=10, eventQuantiles=16/12, nPtsSim=10000, seed=0) Eff11.Fut8Extd.late seqPlotPHNSubjects(Eff11.Fut8Extd.late)