############################################################################### # # # THIS PROGRAM CALCULATES THE STATISTICAL POWER OF PRECLINICAL HIV VACCINE # # AND MICROBICIDE TRIALS CONDUCTED WITH LOW VIRAL CHALLENGE DOSES # # # # IT IS WRITTEN IN THE STATISTICAL COMPUTING LANGUAGE R # # # # FOR DOCUMENTATION CONSULT THE ARTICLE: # # Roland R Regoes, Ira M Longini Jr, Mark B Feinberg & Silvija I Staprans # # Preclinical assessment of HIV vaccine and microbicides by repeated low-dose # # virus challenges. # # PLoS Medicine, 2005. # # # # Copyright (C) 2005 Roland R. Regoes (rregoes@emory.edu) # # # # This program is free software; you can redistribute it and/or # # modify it under the terms of the GNU General Public License # # as published by the Free Software Foundation; either version 2 # # of the License, or (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # # ############################################################################### ############################################################################### # THIS FUNCTION CALCULATES THE STATISTICAL POWER FOR A PRECLINICAL VACCINE # TRIAL # # VARIABLES: # n : number of animals per group (control,vaccinated) # VEs : vaccine efficacy # pc : infection probability of control animal (default=1/2) # Cmax : maximum number of challenge performed on one animal # (default=1) # CV : coefficient of variation of the infectivity distribution # This parameter effectively determines the level of # heterogeneity in susceptibility (default=0) # nexperiments: number of virtual experiments performed for power # estimation (default=1000) # power.fct <- function(n,VEs,pc=1/2,Cmax=1,CV=0,nexperiments=1000){ alpha<-0.05 #set significance level power<-0 #initialize variable power if(CV==0) p<-array(c(rep(pc,n),rep((1-VEs)*pc,n)), dim=c(n,2), dimnames=list(animal=NULL, treatment=c("control","vaccinated"))) for(iexp in 1:nexperiments){ # DEFINE p FOR EACH ANIMAL IN EACH GROUP if CV not 0 if(CV!=0) p<-array(c(rbeta(n,(1-(1+CV^2)*pc)/(CV^2), ((1+CV^2)*pc^2-(2+CV^2)*pc+1)/(CV^2*pc)), rbeta(n,(1-(1+CV^2)*(1-VEs)*pc)/(CV^2), ((1+CV^2)*((1-VEs)*pc)^2-(2+CV^2)*(1-VEs)*pc+1) /(CV^2*(1-VEs)*pc))), dim=c(n,2), dimnames=list(animal=NULL, treatment=c("control","vaccinated"))) # GENERATE DATA ########################################################### # # DEFINE VECTOR OF NUMBER OF CHALLENGES OF EACH ANIMAL y<-array(Cmax,dim=c(n,2), dimnames=list(animal=NULL,treatment=c("control","vaccinated"))) # DEFINE VECTOR OF INFECTION SUCCESS FOR EACH ANIMAL s<-array(0,dim=c(n,2), dimnames=list(animal=NULL,treatment=c("control","vaccinated"))) # DEFINE VECTOR NUMBER OF CHALLENGES IN EACH GROUP eta <-c(control=0,vaccinated=0) # DEFINE VECTOR NUMBER OF CHALLENGES IN EACH GROUP iota<-c(control=0,vaccinated=0) for(treatment in c("control","vaccinated")){ for(ianimal in 1:n){ infected<-FALSE for(ichallenge in 1:Cmax){ if(!infected){ infected<-as.logical(rbinom(1,1,p[ianimal,treatment])) # ^^^^^^ # THIS IS THE BERNOULLI TRIAL THAT SIMULATES # VIRAL CHALLENGE OF AN ANIMAL y[ianimal,treatment]<-ichallenge } } s[ianimal,treatment]<-as.numeric(infected) } # CALCULATE iota and eta ################################################ # eta[treatment] <-sum(y[,treatment]) iota[treatment]<-sum(s[,treatment]) } # CALCULATE pvalue ######################################################## # pvalue<-fisher.test(cbind(iota,eta-iota),alternative="greater")$p.value # CHECK FOR SIGNIFICANCE ################################################## # if(pvalue < alpha) power<-power+1/nexperiments }# close iexp-loop power } ############################################################################### ############################################################################### # THIS FUNCTION CALCULATES THE STATISTICAL POWER FOR A PRECLINICAL VACCINE # TRIAL FOR LARGE NUMBERS OF ANIMALS n # power.asymptotics <- function(n,VEs,Cmax=1){ pc<- 1/2 pv<- (1-VEs)*pc eta.c <- n*(1-(1-pc)^Cmax)/pc # geometric series: sum(n*(1-pc)^(0:(Cmax-1))) eta.v <- n*(1-(1-pv)^Cmax)/pv # geometric series: sum(n*(1-pv)^(0:(Cmax-1))) SD <- sqrt(pc*(1-pc)/eta.c+pv*(1-pv)/eta.v) cc <- (1/eta.c+1/eta.v)/2 # continuity correction # see eg Fleiss JL (1981), Statistical Methods # for Rates and Proportions, pp26-27 alpha<-0.05 z.alpha<-qnorm(1-alpha) 1-pnorm(z.alpha-(pc-pv-cc)/SD) # see Alan Agresti (1996) Categorical Data Analysis, p240 # and Newcombe (1998), Statist. in Med. p875 } ############################################################################### ############################################################################### # # USAGE: # # First save this script on your computer. Then call R and source the script: # source("") # # # To calculate the power of a single challenge trial with 10 animals # per group execute: # power.fct(n=10,VEs=0.9,pc=1/2,Cmax=1,CV=0,nexperiments=1000) # # or shorter: # power.fct(10,0.9) # # # To calculate the power of a repeated challenge trial with 10 animals # per group execute: # power.fct(n=10,VEs=0.9,pc=1/2,Cmax=20,CV=0,nexperiments=1000) # # or shorter: # power.fct(10,0.9,Cmax=20) # # # The function power.asymptotics() can be used analogously, but does not # yield good estimates of the power for small number of animals, n, since # it is based on large sample asymptotics. It runs much faster though # because it does not involve simulating experiments. # ############################################################################### ############################################################################### # # RUNTIME OF power.fct(): # # To get an estimate of cpu usage of power.ftc() on your system outcomment # the lines below before you source this script. This will give you the # estimated cpu-time for nexperiment=1000. The cpu-time scales linearly with # nexperiment. # #cat("n\tVEs\tCmax\tcputime\n\n") #for(n in c(5,10,20)){ # for(ves in c(0.67,0.9)){ # for(cmax in c(1,20)){ # cat(paste(n,ves,cmax, # signif(system.time(power.fct(n,ves,pc=1/2,Cmax=cmax))[1],3), # "\n",sep="\t")) # } # } #} #rm(n,ves,cmax) # ###############################################################################