#################################################################################################################################################################### ############ Randomized phase II trial designs with biomarkers ## Version 05-21-12 ## Freidlin et al JCO submitted 2012 ## For time-to-event endpoint, e.g., progression-free survival (pfs). ## The program requires loading the survival package. ## It assumes an exponential distribution of time-to-event and uniform distribution of accrual. ## For a given clinical setting and design parameters the programs provides the probability of making one of 4 ## recommendations for further development: ## 1) No further testing ## 2) Biomarker-enrichment design phase III design ## 3) Biomarker-stratified design phase III design ## 4) Drop biomarker (use standard phase III design) ## # clinical setting parameters # prev.p prevalence of the biomarker among patients with available biomarker status # pfsbp1 target median pfs for biomarker-positive patients on the experimental arm (months) # pfsbn1 target median pfs for biomarker-negative patients on the experimental arm (months) # pfsbp0 assumed median pfs for biomarker-positive patients on the control arm (months) # pfsbn0 assumed median pfs for biomarker-negative patients on the control arm (months) # design parameters # ebp number of events required for the biomarker-positive subgroup analysis (default 56) # pv.bp significance level for biomarker-positive subgroup in Step 1 (default .1) # pv.o significance level for overall population (all randomized patients) in Step 2A (default .05) # ci2b level of CI for hazard ratio in Step 2B (default 0.80) # hrc.l low hazard ratio cutoff for recommending biomarker-enriched phase III in Step 2B (default 1.3) # hrc.u upper hazard ratio cutoff for recommending dropping the biomarker in Step 2B (default 1.5) #accrual parameters # ssbp minimum sample size for biomarker-positive subgroup, accrual continues until this number is # reached (default 70) # ssbp.max the maximum number of over-accrual in biomarker-positive subgroup, accrual to the entire trial stops after # this number is reached(default 140, ssbp.max must be > ssbp) # ssbn the maximum accrual number in biomarker-negative subgroup, accrual to biomarker-negative # subgroup stops after this number is reached (default 140) # ssbn.min accrual to biomarker-negative subgroup continues until either this number is reached or ssbp.max # biomarker-positive patients are enrolled (default 70, ssbn.min must be < than ssbn) # acr.r accrual rate (per month) # sample call using default parameter values from Freidlin et al paper: use the line below to run the program with # the desired parameters # rp2bm(prev.p=.33,ssbp=70,ssbp.max=140,ssbn=140,ssbn.min=70,pfsbp1=8,pfsbp0=4,pfsbn1=4,pfsbn0=4,acr.r=10,ebp=56,pv.bp=.1,pv.o=.05,ci2b=.8,hrc.l=1.3,hrc.u=1.5) # The program takes approximately 1.5 minutes to run with 10,000 replications on a MS Windows laptop # with Intel Core I7 processor ####################################################################################################################################################################### library(survival) rp2bm<-function(prev.p,ssbp,ssbp.max,ssbn,ssbn.min,pfsbp1,pfsbp0,pfsbn1,pfsbn0,acr.r,ebp,pv.bp,pv.o,ci2b,hrc.l,hrc.u,nsim=10000){ set.seed(179) ss<-ssbp+ssbn ssmax<-floor(4*ssbp/min(prev.p,1-prev.p)) tms0<-matrix(0,ssmax,12) dec<-matrix(0,nsim,1) pvec<-matrix(0,nsim,14) asvec<-matrix(0,nsim,6) atvec<-matrix(0,nsim,6) for (isim in 1:nsim) { tms<-tms0 #patient entry times tms[1:ssmax,3]<-runif(ssmax)*ssmax/acr.r #biomarker status tms[(1:ssmax),2]<-rbinom(ssmax,1,prev.p) #order by entry times in each biomarker group tv1<-tms[tms[,2]==1,] tv1<-tv1[order(tv1[,3]),] tv2<-tms[tms[,2]==0,] tv2<-tv2[order(tv2[,3]),] # treatment assignment stratified by biomarker tv1[1+c(0:(dim(tv1)[1]/2-1))*2,1]<-1 tv2[1+c(0:(dim(tv2)[1]/2-1))*2,1]<-1 #progression times tv1[tv1[,1]==0,4]<-rexp(sum(tv1[,1]==0),rate=log(2)/pfsbp0) tv2[tv2[,1]==0,4]<-rexp(sum(tv2[,1]==0),rate=log(2)/pfsbn0) tv1[tv1[,1]==1,4]<-rexp(sum(tv1[,1]==1),rate=log(2)/pfsbp1) tv2[tv2[,1]==1,4]<-rexp(sum(tv2[,1]==1),rate=log(2)/pfsbn1) tabp<-tv1[ssbp,3] tabp.max<-tv1[ssbp.max,3] tabn<-tv2[ssbn,3] tabn.min<-tv2[ssbn.min,3] if (tabp>=tabn.min) tms<-rbind(tv1[1:ssbp,],tv2[1:min(sum(tv2[,3]<=tabp),ssbn),]) else {if (tabp=tabn.min ) tms<-rbind(tv1[1:sum(tv1[,3]<=tabn.min),],tv2[1:ssbn.min,]) else if (tabp.max=tms[,4]),1,0) #bp results tv<-survdiff(Surv(tms[(tms[,2]==1),6],tms[(tms[,2]==1),7])~tms[(tms[,2]==1),1]) pvec[isim,1]<-tv$chisq*((tv$exp[2]-tv$obs[2])>0) pvec[isim,10]<-sum(tv$obs) #overall results tv<-survdiff(Surv(tms[,6],tms[,7])~tms[,1]) pvec[isim,2]<-tv$chisq*((tv$exp[2]-tv$obs[2])>0) pvec[isim,11]<-sum(tv$obs) # testing the low HR cutoff in bn tv<-coxph(Surv(tms[(tms[,2]==0),6],tms[(tms[,2]==0),7])~tms[(tms[,2]==0),1],method="breslow") pvec[isim,5]<--tv$coefficients+qnorm(1-(1-ci2b)/2)*sqrt(tv$var) # testing the high HR cutoff in bn pvec[isim,6]<--tv$coefficients-qnorm(1-(1-ci2b)/2)*sqrt(tv$var) } pvec[,1:2]<-(1-pchisq(pvec[,1:2],df=1))/2 pvec[,1]<-(pvec[,1]log(hrc.u)) powerb<-colSums(pvec[,1:2])/nsim power2<-sum(pvec[,5])/nsim power3<-sum(pvec[,6])/nsim dec<-ifelse(pvec[,1]==0,ifelse(pvec[,2]==1,4,1),ifelse(pvec[,5]==1,2,ifelse(pvec[,6]==1,4,3))) print("Randomized Phase II Design With Biomarkers") print("Probability of design recommendation:") print(c("No further testing" ,sum(dec==1)/nsim)) print(c("Biomarker-enrichment design" ,sum(dec==2)/nsim)) print(c("Biomarker-stratified design" ,sum(dec==3)/nsim)) print(c("Drop Biomarker (standard phase III)",sum(dec==4)/nsim)) print(" ") print (c("average sample size biomarker-positive subgroup" ,mean(pvec[,13]))) print (c("average sample size biomarker-negative subgroup" ,mean(pvec[,14]))) print (c("power in biomarker-positive subgroup ",powerb[1])) print (c("power in overall population ",powerb[2])) }