From noreply at r-forge.r-project.org Sat Jun 1 16:19:12 2013 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sat, 1 Jun 2013 16:19:12 +0200 (CEST) Subject: [Gsdesign-commits] r353 - in pkg/gsDesign: . R man vignettes Message-ID: <20130601141912.A83F91855A5@r-forge.r-project.org> Author: keaven Date: 2013-06-01 16:19:11 +0200 (Sat, 01 Jun 2013) New Revision: 353 Added: pkg/gsDesign/vignettes/ pkg/gsDesign/vignettes/gsSurvTemplate.rnw pkg/gsDesign/vignettes/gsSurvTemplateInstructions.rnw Modified: pkg/gsDesign/R/gsSurv.R pkg/gsDesign/man/gsBoundSummary.Rd Log: Additional minor 2.8 updates, including vignettes for time-to-event endpoints. Modified: pkg/gsDesign/R/gsSurv.R =================================================================== --- pkg/gsDesign/R/gsSurv.R 2013-05-29 13:34:09 UTC (rev 352) +++ pkg/gsDesign/R/gsSurv.R 2013-06-01 14:19:11 UTC (rev 353) @@ -4,55 +4,57 @@ eEvents1<-function(lambda=1, eta=0, gamma=1, R=1, S=NULL, T=2, Tfinal=NULL, minfup=0, simple=TRUE) { - if (is.null(Tfinal)) - { Tfinal <- T - minfupia <- minfup - } - else minfupia <- max(0, minfup-(Tfinal - T)) - - nlambda <- length(lambda) - if (length(eta)==1 & nlambda > 1) - eta <- array(eta,nlambda) - T1 <- cumsum(S) - T1 <- c(T1[T1length(unique(T2))] <- 0 - T2 <- unique(c(T,T2[T2 > 0])) - T3 <- sort(unique(c(T1,T2))) - if (sum(R) >= T) T2 <- c(T2,0) - nperiod <- length(T3) - s <- T3-c(0,T3[1:(nperiod-1)]) - - lam <- array(lambda[nlambda],nperiod) - et <- array(eta[nlambda],nperiod) - gam <- array(0,nperiod) - - for(i in length(T1):1) - { indx <- T3<=T1[i] - lam[indx]<-lambda[i] - et[indx]<-eta[i] - } - for(i in min(length(gamma)+1,length(T2)):2) - gam[T3>T2[i]]<-gamma[i-1] - q <- exp(-(lam+et)*s) - Q <- cumprod(q) - indx<-1:(nperiod-1) - Qm1 <- c(1,Q[indx]) - p <- lam/(lam+et)*Qm1*(1-q) - P <- cumsum(p) - B <- gam/(lam+et)*lam*(s-(1-q)/(lam+et)) - A <- c(0,P[indx])*gam*s+Qm1*B - if (!simple) - return(list(lambda=lambda, eta=eta, gamma=gamma, R=R, S=S, - T=T, Tfinal=Tfinal, minfup=minfup, d=sum(A), - n=sum(gam*s), q=q,Q=Q,p=p,P=P,B=B,A=A,T1=T1, - T2=T2,T3=T3,lam=lam,et=et,gam=gam)) - else - return(list(lambda=lambda, eta=eta, gamma=gamma, R=R, S=S, - T=T, Tfinal=Tfinal, minfup=minfup, d=sum(A), - n=sum(gam*s))) + if (is.null(Tfinal)) + { Tfinal <- T + minfupia <- minfup + } + else minfupia <- max(0, minfup-(Tfinal - T)) + + nlambda <- length(lambda) + if (length(eta)==1 & nlambda > 1) + eta <- array(eta,nlambda) + T1 <- cumsum(S) + T1 <- c(T1[T1length(unique(T2))] <- 0 + T2 <- unique(c(T,T2[T2 > 0])) + T3 <- sort(unique(c(T1,T2))) + if (sum(R) >= T) T2 <- c(T2,0) + nperiod <- length(T3) + s <- T3-c(0,T3[1:(nperiod-1)]) + + lam <- array(lambda[nlambda],nperiod) + et <- array(eta[nlambda],nperiod) + gam <- array(0,nperiod) + + for(i in length(T1):1) + { indx <- T3<=T1[i] + lam[indx]<-lambda[i] + et[indx]<-eta[i] + } + for(i in min(length(gamma)+1,length(T2)):2) + gam[T3>T2[i]]<-gamma[i-1] + q <- exp(-(lam+et)*s) + Q <- cumprod(q) + indx<-1:(nperiod-1) + Qm1 <- c(1,Q[indx]) + p <- lam/(lam+et)*Qm1*(1-q) + p[is.nan(p)] <- 0 + P <- cumsum(p) + B <- gam/(lam+et)*lam*(s-(1-q)/(lam+et)) + B[is.nan(B)]<-0 + A <- c(0,P[indx])*gam*s+Qm1*B + if (!simple) + return(list(lambda=lambda, eta=eta, gamma=gamma, R=R, S=S, + T=T, Tfinal=Tfinal, minfup=minfup, d=sum(A), + n=sum(gam*s), q=q,Q=Q,p=p,P=P,B=B,A=A,T1=T1, + T2=T2,T3=T3,lam=lam,et=et,gam=gam)) + else + return(list(lambda=lambda, eta=eta, gamma=gamma, R=R, S=S, + T=T, Tfinal=Tfinal, minfup=minfup, d=sum(A), + n=sum(gam*s))) } ################################################### ### code chunk number 4: eEvents Modified: pkg/gsDesign/man/gsBoundSummary.Rd =================================================================== --- pkg/gsDesign/man/gsBoundSummary.Rd 2013-05-29 13:34:09 UTC (rev 352) +++ pkg/gsDesign/man/gsBoundSummary.Rd 2013-06-01 14:19:11 UTC (rev 353) @@ -1,6 +1,5 @@ \name{gsBoundSummary} \alias{gsBoundSummary} -\alias{xtable.gsDesign} \alias{gsBValue} \alias{gsDelta} \alias{gsHR} @@ -10,7 +9,7 @@ \title{2.8: Bound Summary and Z-transformations} \description{Z-value test statistic transformations are commonly used as supplementary descriptions of bounds. -\code{gsBoundSummary()} summarizes a bound for a group sequential design with by computing several of these design characteristics. \code{xtable.gsDesign} produces Latex output of boundary summary information; intended for use with \code{Sweave()}. +\code{gsBoundSummary()} summarizes a bound for a group sequential design with by computing several of these design characteristics. Individual transformation of z-value test statistics for interim and final analyses are obtained from \code{gsBValue()}, \code{gsDelta()}, \code{gsHR()} and \code{gsCPz()} for B-values, approximate treatment effect (see details), approximate hazard ratio and conditional power, respectively. @@ -23,10 +22,6 @@ gsRR(z, i, x, ratio=1, ylab="Estimated risk ratio",...) gsCPz(z, i, x, theta=NULL, ylab=NULL, ...) gsBoundSummary(x, upper=TRUE, ratio=1) - \method{xtable}{gsDesign}(x, caption=NULL, label=NULL, align=NULL, digits=c(0,0,3,4,4,4,3,3,3,3), - display=NULL, upper=TRUE, rnames=NULL, cnames=NULL, ratio=1, - sanitize.text.function=function(x){x}, - sanitize.rownames.function=function(x){x},...) } \arguments{ @@ -37,17 +32,7 @@ \item{theta}{A scalar value used for conditional power calculations; see \code{gsDesign}; if NULL, conditional power is computed at the estimated interim treatment effect based on \code{z}} \item{ylab}{Used when functions are passed to \code{plot.gsDesign} to establish default y-axis labels} \item{ratio}{Used only for time-to-event studies; randomization ratio for experimental versus control group} - \item{digits}{An integer vector containing the digits to be displayed for each row} - \item{rnames}{Allows user to override default row names for output matrix} - \item{cnames}{Allows user to override default column names for output matrix} - \item{...}{This allows many optional arguments that are standard when calling \code{xtable} and \code{plot}} - \item{caption}{See dcoumentation for \code{xtable}} - \item{label}{See dcoumentation for \code{xtable}} - \item{align}{See dcoumentation for \code{xtable}} - \item{display}{See dcoumentation for \code{xtable}} - \item{sanitize.text.function}{Should be able to use default; see documentation for \code{xtable}}, - \item{sanitize.rownames.function}{Should be able to use default; see documentation for -\code{xtable} and \code{print}} + \item{...}{This allows many optional arguments that are standard when calling \code{plot}} } \value{ @@ -80,12 +65,6 @@ # lower bound summary gsBoundSummary(x, upper=FALSE) -# print upper bound summary in latex format -xtable(x) - -# print lower bound summary in latex format -xtable(x, upper=FALSE) - # now derive a design with a time-to-event endpoint # note that by specifying endpoint="Survival", hazard ratio replaces treatment effect ns <- nSurvival() Added: pkg/gsDesign/vignettes/gsSurvTemplate.rnw =================================================================== --- pkg/gsDesign/vignettes/gsSurvTemplate.rnw (rev 0) +++ pkg/gsDesign/vignettes/gsSurvTemplate.rnw 2013-06-01 14:19:11 UTC (rev 353) @@ -0,0 +1,170 @@ +\documentclass{article} +\usepackage[round]{natbib} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands. +% \VignetteIndexEntry{Template for time-to-event group sequential design} +% \VignetteEngine{knitr} +\begin{document} +\title{Template for time-to-event group sequential design} +\author{Keaven M. Anderson} +\maketitle +<>= +options(width=58) +@ +\section{Introduction} +This vignette provides a template for time-to-event sample size calculations for fixed designs using \texttt{nSurv} and group sequential designs using \texttt{gsSurv}. +Edit this template (from gsDesign R package source \verb@/inst/doc/gsSurvTemplate.rnw@) so that you can reuse it on a regular basis for sample size calculations for time-to-event study planning. +The template only uses the simplest options with a single stratum and exponential failure and dropout rates. +The template can be modified to accomodate multiple strata and/or piecewise exponential failure and dropout rates; this was not chose here since the more simplest options are a) often used and b) simplest to learn and apply for beginners. +Note that we produce tabular, textual and graphical output; examining the source file to see how this is done will enable you to easily customize to fit your purposes. +You will need the knitr R package, which I find simpler to use than Sweave (although you could make minor edits and use Sweave). +I have found using knitr and the RStudio development environment to be a good combination. +Within this template, we suppress printing of all of the code used to generate results. +The file \verb@/inst/doc/gsSurvTemplateInstructions.pdf@ is an alternate version of this document that shows code associated with this template. + + +We apply the \citet{LachinFoulkes} sample size method and extend it to group sequential design. +This method fixes the duration of a study and varies enrollment rates to power a trial. +{Alternate text: \em We use the \citet{LachinFoulkes} basic power equation to compute sample size along the lines of \citet{KimTsiatis} where enrollment rates are fixed and enrollment duration is allowed to vary to enroll a sufficient sample size to power a study.} +The sample size method assumes proportional hazards between treatment groups. +Accrual of events of events over time is approximated assuming failure rates are exponential. + +<>= +# code here applies to both fixed and group sequential design sections below. +require(gsDesign) +# enrollment period durations; the last of these will be extended if T=NULL below +R <- c(1,2,3,4) +# relative enrollment rates during above periods +gamma<-c(1,1.5,2.5,4) +# study duration +# T can be set to NULL if you want to +# fix enrollment and vary study duration +T <- 36 +# follow-up duration of last patient enrolled +minfup <- 12 +# randomization ratio, experimental/control +ratio <- 1 +# median control time-to-event +median <- 12 +# exponential dropout rate per unit of time +eta <- .001 +# hypothesized experimental/control hazard ratio +hr <- .75 +# null hazard ratio (1 for superiority, >1 for non-inferiority) +hr0 <- 1 +# Type I error (1-sided) +alpha <-.025 +# Type II error (1-power) +beta<-.2 +x <- nSurv(R=R,gamma=gamma,eta=eta,minfup=minfup, + T=T,lambdaC=log(2)/median, + hr=hr,hr0=hr0,beta=beta,alpha=alpha) +# time units +timename <- "months" +timename1 <- "month" +# endpoint name +ep <-"overall survival" +# make a string with enrollment rates (assumes gamma is a single value or vector) +nR <- length(x$R) +if (nR==1){enrolrates <- paste("constant at a rate of ",round(gamma,1),"per",timename1,".") +} else{ +enrolrates <- paste(c("piecewise constant at rates of ", + paste(round(as.vector(x$gamma),1)," for ",timename," ",cumsum(c(0,x$R[1:(nR-1)])), + "-",cumsum(x$R),collapse=", "),sep=""),collapse="") +} +@ + +\subsection{Fixed design sample size} +{\em This section can be deleted if you are only interested in group sequential design.} +The median time-to-event is assumed to be \Sexpr{median} \Sexpr{timename} in the control group. +\Sexpr{if (hr0==1) paste("The trial is designed to demonstrate superiority of experimental treatment over control with an assumed hazard ratio of ",hr)} \Sexpr{if (hr0 != 1) paste("The trial is designed to reject a null hypothesis hazard ratio of ",hr0," in favor of a hazard ratio of",hr)} with \Sexpr{100*(1-beta)}\% power and a one-sided Type I error rate of \Sexpr{100*alpha}. +The total sample size is \Sexpr{2*ceiling(x$n/2)} and a +total of \Sexpr{ceiling(x$d)} endpoints is required for analysis. +Planned recruitment duration is \Sexpr{sum(x$R)} \Sexpr{timename} and the minimum follow-up planned is \Sexpr{round(x$minfup,1)} \Sexpr{timename}. +Thus, the total expected study duration is \Sexpr{round(max(x$T),1)} \Sexpr{timename}. +Enrollment is assumed to be \Sexpr{enrolrates}. +The assumed dropout rate is \Sexpr{100*eta}\% per \Sexpr{timename1}. + +\section{Group sequential design} + +<>= +# number of analyses (interim + final) +k <- 2 +# timing of interim analyses (k-1 increasing numbers >0 and <1) +timing <- c(.4) +# efficacy bound spending function +sfu <- sfHSD +# efficacy bound spending parameter specification +sfupar <- -10 +# futility bound spending function +sfl <- sfHSD +# futility bound spending parameter specification +sflpar <- 2 +# footnote text for table +footnote <- paste("P\\{Cross\\} is the probability of crossing the given bound (efficacy or futility) at or before the given analysis under the assumed hazard ratio (HR). Design assumes futility bound is discretionary (non-binding), but smaller upper boundary crossing probabilities shown here assume trial stops at first boundary crossing (binding bounds).") +# caption text for table +caption <- paste("Overall survival trial design with HR=",hr,", ",100*(1-beta),"\\% power and ",100*alpha,"\\% Type 1 error.",sep="") +# generate design +x <- gsSurv(k=k,timing=timing,R=R,gamma=gamma,eta=eta, + minfup=minfup,T=T,lambdaC=log(2)/median, + hr=hr,hr0=hr0,beta=beta,alpha=alpha, + sfu=sfu,sfupar=sfupar,sfl=sfl,sflpar=sflpar) +# make a string with enrollment rates (assumes gamma is a single value or vector) +nR <- length(x$R) +if (nR==1){enrolrates <- paste("constant at a rate of ",round(gamma,1),"per",timename1,".") +} else{ +enrolrates <- paste(c("piecewise constant at rates of ", + paste(round(as.vector(x$gamma),1)," for ",timename," ",cumsum(c(0,x$R[1:(nR-1)])), + "-",cumsum(x$R),collapse=", "),sep=""),collapse="") +} +@ + +For a comparative trial we consider a 2-arm group sequential design with \Sexpr{ep} as the primary endpoint as shown in Table \ref{tab1}. +Timing, number of events, sample size, boundaries (Z-values, nominal p-values, approximate hazard ratios) are shown as well as the probability of crossing study boundaries under the null and alternate hypotheses. +Bounds are determined by Hwang-Shih-DeCani spending functions with $\gamma=\Sexpr{sfupar}$ ($\alpha$-spending) and $\gamma=\Sexpr{sflpar}$ ($\beta$-spending). +The median time-to-event is assumed to be \Sexpr{median} \Sexpr{timename} in the control group. +\Sexpr{if (hr0==1) paste("The trial is designed to demonstrate superiority of experimental treatment over control with an assumed hazard ratio of ",hr,".",sep="")} +The total sample size is \Sexpr{ceiling(sum(x$eNE[k,]+x$eNC[k,]))} and a +total of \Sexpr{ceiling(sum(x$eDE[k,]+x$eDC[k,]))} endpoints is required for the final analysis. +Planned recruitment duration is \Sexpr{sum(x$R)} \Sexpr{timename} and the minimum follow-up planned is \Sexpr{round(x$minfup,1)} \Sexpr{timename}. +Thus, the total expected study duration is \Sexpr{round(max(x$T),1)} \Sexpr{timename}. +Enrollment is assumed to be \Sexpr{enrolrates}. +The assumed dropout rate is \Sexpr{100*eta}\% per \Sexpr{timename1}. +\Sexpr{if (x$k==2) paste("There is a single interim analysis planned after",ceiling(x$eDE[1,]+x$eDC[1,]),"events have accrued which is expected after approximately",round(x$T[1],1),timename,sep=" ")}. + +<>= +print(xtable(x,footnote=footnote,caption=caption, + label="tab1"), + include.rownames=F, + sanitize.text.function=function(x) x) +@ +Following are plots of the Z-values (Figure \ref{fig:p1}) and approximate hazard ratios (Figure \ref{fig:p2}) at the design bounds. +<>= +plot(x,cex=.8,xlab="Number of events") +@ +<>= +plot(x,plottype="hr",cex=.8,xlab="Number of events") +@ +\newif\ifabfull\abfulltrue +\begin{thebibliography}{2} +\providecommand{\natexlab}[1]{#1} +\providecommand{\url}[1]{\texttt{#1}} +\expandafter\ifx\csname urlstyle\endcsname\relax + \providecommand{\doi}[1]{doi: #1}\else + \providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi + +\bibitem[Kim and Tsiatis(1990)]{KimTsiatis} +Kyungmann Kim and Anastasios~A. Tsiatis. +\newblock Study duration for clinical trials with survival response and early + stopping rule. +\newblock \emph{Biometrics}, 46:\penalty0 81--92, 1990. + +\bibitem[Lachin and Foulkes(1986)]{LachinFoulkes} +John~M. Lachin and Mary~A. Foulkes. +\newblock Evaluation of sample size and power for analyses of survival with + allowance for nonuniform patient entry, losses to follow-up, noncompliance, + and stratification. +\newblock \emph{Biometrics}, 42:\penalty0 507--519, 1986. + +\end{thebibliography} + +\end{document} Added: pkg/gsDesign/vignettes/gsSurvTemplateInstructions.rnw =================================================================== --- pkg/gsDesign/vignettes/gsSurvTemplateInstructions.rnw (rev 0) +++ pkg/gsDesign/vignettes/gsSurvTemplateInstructions.rnw 2013-06-01 14:19:11 UTC (rev 353) @@ -0,0 +1,200 @@ +\documentclass{article} +\usepackage[round]{natbib} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands. +% \VignetteIndexEntry{Template instructions for time-to-event group sequential design} +% \VignetteEngine{knitr} +\begin{document} +\title{Template instructions for time-to-event group sequential design} +\author{Keaven M. Anderson} +\maketitle +<>= +options(width=58) +@ +\section{Introduction} +This vignette provides a template for time-to-event sample size calculations for fixed designs using \texttt{nSurv} and group sequential designs using \texttt{gsSurv}. +It may be useful to edit this template (found in the source for the gsDesign R package in \verb@/inst/doc/gsSurvTemplate.rnw@) so that you can reuse it on a regular basis for sample size calculations for time-to-event study planning. +The template only uses the simplest options with a single stratum and exponential failure and dropout rates. +The template can be modified to accomodate multiple strata and/or piecewise exponential failure and dropout rates; this was not chose here since the more simplest options are a) often used and b) simplest to learn and apply for beginners. +Note that we produce tabular, textual and graphical output; examining the source file to see how this is done will enable you to easily customize to fit your purposes. +You will need the knitr R package, which I find simpler to use than Sweave (although you could make minor edits and use Sweave). +I have found using knitr and the RStudio development environment to be a good combination. +Within this template, we generally show all of the code used to generate results. You will want to suppress this in your own template. + + +We apply the \citet{LachinFoulkes} sample size method and extend it to group sequential design. +This method fixes the duration of a study and varies enrollment rates to power a trial. +We also use the \citet{LachinFoulkes} basic power equation to compute sample size along the lines of \citet{KimTsiatis} where enrollment rates are fixed and enrollment duration is allowed to vary to enroll a sufficient sample size to power a study. +While \texttt{nSurv} and \texttt{gsSurv} allow stratified populations and piecewise exponential failure rates, we restrict ourselves to a single stratum with an exponential failure distribution here; see the help file for \texttt{gsSurv} for examples with a stratified population or piecewise exponential failure. + +Some detail in specification comes with the flexibility allowed by the \citet{LachinFoulkes} method. +Thus a template is helpful to simplify use. + +We present a relatively simple example of time-to-event sample size calculation for a group sequential design. + + +\subsection{Basic assumptions and fixed design sample size} +Following is code using the gsDesign R package. +The first chunk of code sets up enrollment and dropout information. +<>= +require(gsDesign) +# enrollment period durations; the last of these will be extended if T=NULL below +R <- c(1,2,3,4) +# relative enrollment rates during above periods +gamma<-c(1,1.5,2.5,4) +# study duration +# T can be set to NULL if you want to +# fix enrollment and vary study duration +T <- 36 +# follow-up duration of last patient enrolled +minfup <- 12 +# randomization ratio, experimental/control +ratio <- 1 +@ +Next we provide information about the median time to event in the control group, dropout rate, hazard ratios under the null and alternate hypotheses for experimental therapy compared to control, and the desired Type I and II error rates. +<>= +# median control time-to-event +median <- 12 +# exponential dropout rate per unit of time +eta <- .001 +# hypothesized experimental/control hazard ratio +hr <- .75 +# null hazard ratio (1 for superiority, >1 for non-inferiority) +hr0 <- 1 +# Type I error (1-sided) +alpha <-.025 +# Type II error (1-power) +beta<-.1 +@ +Finally, we design a trial with no interim analyses under these assumptions. +Note that when calling \texttt{nSurv}, we transform the median time-to-event ($m$) to an exponential event rate ($\lambda$) with the formula +$$\lambda=\log(2)/m.$$ +<>= +x <- nSurv(R=R,gamma=gamma,eta=eta,minfup=minfup, + T=T,lambdaC=log(2)/median, + hr=hr,hr0=hr0,beta=beta,alpha=alpha) +@ +Next we store some text for use in output; only need to edit \texttt{timename}, \texttt{timename1} and \texttt{ep} as the following code is used to format enrollment rate input from above. See the following paragraph below to see where this text is used. +<>= +# time units +timename <- "months" +timename1 <- "month" +# endpoint name +ep <-"overall survival" +# make a string with enrollment rates (assumes gamma is a single value or vector) +nR <- length(x$R) +if (nR==1){enrolrates <- paste("constant at a rate of ",round(gamma,1),"per",timename1,".") +} else{ +enrolrates <- paste(c("piecewise constant at rates of ", + paste(round(as.vector(x$gamma),1)," for ",timename," ",cumsum(c(0,x$R[1:(nR-1)])), + "-",cumsum(x$R),collapse=", "),sep=""),collapse="") +} +@ + +The median time-to-event is assumed to be \Sexpr{median} \Sexpr{timename} in the control group. +\Sexpr{if (hr0==1) paste("The trial is designed to demonstrate superiority of experimental treatment over control with an assumed hazard ratio of ",hr)} \Sexpr{if (hr0 != 1) paste("The trial is designed to reject a null hypothesis hazard ratio of ",hr0," in favor of a hazard ratio of",hr)} with \Sexpr{100*(1-beta)}\% power and a one-sided Type I error rate of \Sexpr{100*alpha}. +The total sample size is \Sexpr{2*ceiling(x$n/2)} and a +total of \Sexpr{ceiling(x$d)} endpoints is required for analysis. +Planned recruitment duration is \Sexpr{sum(x$R)} \Sexpr{timename} and the minimum follow-up planned is \Sexpr{round(x$minfup,1)} \Sexpr{timename}. +Thus, the total expected study duration is \Sexpr{round(max(x$T),1)} \Sexpr{timename}. +Enrollment is assumed to be \Sexpr{enrolrates}. +The assumed dropout rate is \Sexpr{100*eta}\% per \Sexpr{timename1}. + +\section{Group sequential design} +Now we move on to a group sequential design. +We set up the number of analyses, timing and spending function parameters. +<>= +# number of analyses (interim + final) +k <- 2 +# timing of interim analyses (k-1 increasing numbers >0 and <1) +timing <- c(.4) +# efficacy bound spending function +sfu <- sfHSD +# efficacy bound spending parameter specification +sfupar <- -10 +# futility bound spending function +sfl <- sfHSD +# futility bound spending parameter specification +sflpar <- 2 +@ + +Type II error (1-power) may be set up differently than for a fixed design so that more meaningful futility analyses can be performed during the course of the trial. + +<>= +# Type II error=1-Power +beta <- .2 +@ + +<>= +# footnote text for table +footnote <- paste("P\\{Cross\\} is the probability of crossing the given bound (efficacy or futility) at or before the given analysis under the assumed hazard ratio (HR). Design assumes futility bound is discretionary (non-binding), but smaller upper boundary crossing probabilities shown here assume trial stops at first boundary crossing (binding bounds).") +# caption text for table +caption <- paste("Overall survival trial design with HR=",hr,", ",100*(1-beta),"\\% power and ",100*alpha,"\\% Type 1 error.",sep="") +@ + +Now we are prepared to generate the design. +<>= +# generate design +x <- gsSurv(k=k,timing=timing,R=R,gamma=gamma,eta=eta, + minfup=minfup,T=T,lambdaC=log(2)/median, + hr=hr,hr0=hr0,beta=beta,alpha=alpha, + sfu=sfu,sfupar=sfupar,sfl=sfl,sflpar=sflpar) +# make a string with enrollment rates (assumes gamma is a single value or vector) +nR <- length(x$R) +if (nR==1){enrolrates <- paste("constant at a rate of ",round(gamma,1),"per",timename1,".") +} else{ +enrolrates <- paste(c("piecewise constant at rates of ", + paste(round(as.vector(x$gamma),1)," for ",timename," ",cumsum(c(0,x$R[1:(nR-1)])), + "-",cumsum(x$R),collapse=", "),sep=""),collapse="") +} +@ + +For a comparative trial we consider a 2-arm group sequential design with \Sexpr{ep} as the primary endpoint as shown in Table \ref{tab1}. +Timing, number of events, sample size, boundaries (Z-values, nominal p-values, approximate hazard ratios) are shown as well as the probability of crossing study boundaries under the null and alternate hypotheses. +Bounds are determined by Hwang-Shih-DeCani spending functions with $\gamma=\Sexpr{sfupar}$ ($\alpha$-spending) and $\gamma=\Sexpr{sflpar}$ ($\beta$-spending). +The median time-to-event is assumed to be \Sexpr{median} \Sexpr{timename} in the control group. +\Sexpr{if (hr0==1) paste("The trial is designed to demonstrate superiority of experimental treatment over control with an assumed hazard ratio of ",hr,".",sep="")} +The total sample size is \Sexpr{ceiling(sum(x$eNE[k,]+x$eNC[k,]))} and a +total of \Sexpr{ceiling(sum(x$eDE[k,]+x$eDC[k,]))} endpoints is required for the final analysis. +Planned recruitment duration is \Sexpr{sum(x$R)} \Sexpr{timename} and the minimum follow-up planned is \Sexpr{round(x$minfup,1)} \Sexpr{timename}. +Thus, the total expected study duration is \Sexpr{round(max(x$T),1)} \Sexpr{timename}. +Enrollment is assumed to be \Sexpr{enrolrates}. +The assumed dropout rate is \Sexpr{100*eta}\% per \Sexpr{timename1}. +\Sexpr{if (x$k==2) paste("There is a single interim analysis planned after",ceiling(x$eDE[1,]+x$eDC[1,]),"events have accrued which is expected after approximately",round(x$T[1],1),timename,sep=" ")}. + +<>= +print(xtable(x,footnote=footnote,caption=caption, + label="tab1"), + include.rownames=F, + sanitize.text.function=function(x) x) +@ +Following are plots of the Z-values (Figure \ref{fig:p1}) and approximate hazard ratios (Figure \ref{fig:p2}) at the design bounds. +<>= +plot(x,cex=.8,xlab="Number of events") +@ +<>= +plot(x,plottype="hr",cex=.8,xlab="Number of events") +@ +\newif\ifabfull\abfulltrue +\begin{thebibliography}{2} +\providecommand{\natexlab}[1]{#1} +\providecommand{\url}[1]{\texttt{#1}} +\expandafter\ifx\csname urlstyle\endcsname\relax + \providecommand{\doi}[1]{doi: #1}\else + \providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi + +\bibitem[Kim and Tsiatis(1990)]{KimTsiatis} +Kyungmann Kim and Anastasios~A. Tsiatis. +\newblock Study duration for clinical trials with survival response and early + stopping rule. +\newblock \emph{Biometrics}, 46:\penalty0 81--92, 1990. + +\bibitem[Lachin and Foulkes(1986)]{LachinFoulkes} +John~M. Lachin and Mary~A. Foulkes. +\newblock Evaluation of sample size and power for analyses of survival with + allowance for nonuniform patient entry, losses to follow-up, noncompliance, + and stratification. +\newblock \emph{Biometrics}, 42:\penalty0 507--519, 1986. + +\end{thebibliography} + +\end{document} From noreply at r-forge.r-project.org Wed Jun 5 22:14:06 2013 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Wed, 5 Jun 2013 22:14:06 +0200 (CEST) Subject: [Gsdesign-commits] r354 - pkg/gsDesign/man Message-ID: <20130605201406.A5361184773@r-forge.r-project.org> Author: keaven Date: 2013-06-05 22:14:06 +0200 (Wed, 05 Jun 2013) New Revision: 354 Modified: pkg/gsDesign/man/nSurv.Rd pkg/gsDesign/man/nSurvival.Rd pkg/gsDesign/man/ssrCP.Rd Log: Formatting changes in 3 help files (no content change). Modified: pkg/gsDesign/man/nSurv.Rd =================================================================== --- pkg/gsDesign/man/nSurv.Rd 2013-06-01 14:19:11 UTC (rev 353) +++ pkg/gsDesign/man/nSurv.Rd 2013-06-05 20:14:06 UTC (rev 354) @@ -222,10 +222,12 @@ nSurv(lambdaC=log(2)/6, hr=.5, eta=log(2)/40, gamma=6, R=25) # piecewise constant enrollment rates (vary accrual duration) -nSurv(lambdaC=log(2)/6, hr=.5, eta=log(2)/40, gamma=c(1,3,6), R=c(3,6,9), minfup=12) +nSurv(lambdaC=log(2)/6, hr=.5, eta=log(2)/40, gamma=c(1,3,6), + R=c(3,6,9), minfup=12) # stratified population (vary accrual duration) -nSurv(lambdaC=matrix(log(2)/c(6,12),ncol=2), hr=.5, eta=log(2)/40, gamma=matrix(c(2,4),ncol=2), minfup=12) +nSurv(lambdaC=matrix(log(2)/c(6,12),ncol=2), hr=.5, eta=log(2)/40, + gamma=matrix(c(2,4),ncol=2), minfup=12) # piecewise exponential failure rates (vary accrual duration) nSurv(lambdaC=log(2)/c(6,12), hr=.5, eta=log(2)/40, S=3, gamma=6, minfup = 12) @@ -236,9 +238,11 @@ gamma=matrix(c(3,6,5,7),ncol=2), R=c(5,10), minfup = 12) # group sequential design (vary accrual rate to obtain power) -x<-gsSurv(k=4,sfl=sfPower,sflpar=.5,lambdaC=log(2)/6, hr=.5, eta=log(2)/40,gamma=1, T=36, minfup = 12) +x<-gsSurv(k=4,sfl=sfPower,sflpar=.5,lambdaC=log(2)/6, hr=.5, + eta=log(2)/40,gamma=1, T=36, minfup = 12) x -print(xtable(x,footnote="This is a footnote; note that it can be wide.", caption="Caption example.")) +print(xtable(x,footnote="This is a footnote; note that it can be wide.", + caption="Caption example.")) # find expected number of events at time 12 in the above trial nEventsIA(x=x,tIA=10) Modified: pkg/gsDesign/man/nSurvival.Rd =================================================================== --- pkg/gsDesign/man/nSurvival.Rd 2013-06-01 14:19:11 UTC (rev 353) +++ pkg/gsDesign/man/nSurvival.Rd 2013-06-05 20:14:06 UTC (rev 354) @@ -17,7 +17,8 @@ alpha = 0.025, beta = 0.10, sided = 1, approx = FALSE, type = c("rr", "rd"), entry = c("unif", "expo"), gamma = NA) \method{print}{nSurvival}(x,...) -nEvents(hr = .6, alpha = .025, beta = .1, ratio = 1, sided = 1, hr0 = 1, n = 0, tbl = FALSE) +nEvents(hr = .6, alpha = .025, beta = .1, ratio = 1, sided = 1, + hr0 = 1, n = 0, tbl = FALSE) hrn2z(hr, n, ratio=1, hr0=1, hr1=.7) hrz2n(hr, z, ratio=1, hr0=1) zn2hr(z, n, ratio=1, hr0=1, hr1=.7) @@ -98,7 +99,7 @@ \item{Ts}{As input.} \item{Tr}{As input.} - \code{nEvents} produces a scalar or vector of sample sizes (or powers) when \code{tbl=FALSE} or, when \code{tbl=TRUE} a matrix of values with the following columns: + \code{nEvents} produces a scalar or vector of sample sizes (or powers) when \code{tbl=FALSE} or, when \code{tbl=TRUE} a data frame of values with the following columns: \item{hr}{As input.} \item{n}{If \code{n[1]=0} on input (default), output contains the number of events need to obtain the input Type I and II error. If \code{n[1]>0} on input, the input value is returned.} \item{alpha}{As input.} Modified: pkg/gsDesign/man/ssrCP.Rd =================================================================== --- pkg/gsDesign/man/ssrCP.Rd 2013-06-01 14:19:11 UTC (rev 353) +++ pkg/gsDesign/man/ssrCP.Rd 2013-06-05 20:14:06 UTC (rev 354) @@ -7,7 +7,9 @@ If not done carefully, these designs can be very inefficient. It is probably a good idea to compare any design to a simpler group sequential design; see, for example, Jennison and Turnbull, Statistics in Medicine, 2003. Method assumes a small Type I error is included with the interim analysis and that the design is an adaptation from a 2-stage group sequential design (Lehmacher and Wassmer, Biometrics, 1999).} \usage{ -ssrCP(z, theta = NULL, maxinc = 2, overrun = 0, beta = 0.1, cpadj = c(0.5, 1 - beta), x = gsDesign(k = 2, timing = 0.5, beta = beta)) +ssrCP(z, theta = NULL, maxinc = 2, overrun = 0, beta = 0.1, + cpadj = c(0.5, 1 - beta), + x = gsDesign(k = 2, timing = 0.5, beta = beta)) } \arguments{ \item{z}{Scalar or vector with interim standardized Z-value(s). Input of multiple values makes it easy to plot the revised sample size as a function of the interim test statistic.} @@ -65,10 +67,12 @@ # generate a 2-stage group sequential design with # desired planned sample size (first 2 lines set planned sample size to that from above; normally) -x<-gsDesign(k=2,n.fix=n.fix,timing=timing,sfu=sfu,sfupar=sfupar,alpha=alpha,beta=beta) +x<-gsDesign(k=2,n.fix=n.fix,timing=timing,sfu=sfu,sfupar=sfupar, + alpha=alpha,beta=beta) nalt <- maxinflation*(x$n.I[2]) par(mar=c(7, 4, 4, 4)+.1) -plot(z,ssrCP(x=x,z=z,overrun=overrun,beta=betastar,cpadj=cpadj),type="l",xlim=c(0,3.5),axes=FALSE,xlab="",ylab="") +plot(z,ssrCP(x=x,z=z,overrun=overrun,beta=betastar,cpadj=cpadj), + type="l",xlim=c(0,3.5),axes=FALSE,xlab="",ylab="") lines(z,80+240*dnorm(z,mean=0),col=2) lines(z,80+240*dnorm(z,mean=sqrt(x$n.I[1])*x$theta[2]),col=3) lines(z,80+240*dnorm(z,mean=sqrt(x$n.I[1])*x$theta[2]/2),col=4) @@ -80,7 +84,8 @@ lines(x=c(-3.5,3.5),y=c(nalt,nalt),lty=2) w <- x$timing[1] theta <- seq(.5,3.5,.5) / sqrt(x$n.I[1]) -CP <- pnorm(theta*sqrt(x$n.I[2]*(1-w))-(x$upper$bound[2]-seq(.5,3.5,.5)*sqrt(w))/sqrt(1-w)) +CP <- pnorm(theta*sqrt(x$n.I[2]*(1-w))-(x$upper$bound[2]- + seq(.5,3.5,.5)*sqrt(w))/sqrt(1-w)) axis(side=1,line=3,at=seq(.5,3.5,.5),labels=as.character(round(CP,2))) mtext(side=1,"CP",line=3.5,at=.25) axis(side=1,line=1,at=seq(0,3.5,.5),labels=as.character(seq(0,3.5,.5)))