[Gsdesign-commits] r232 - in pkg/gsDesign: . R man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Dec 21 04:05:07 CET 2009


Author: keaven
Date: 2009-12-21 04:05:07 +0100 (Mon, 21 Dec 2009)
New Revision: 232

Modified:
   pkg/gsDesign/NAMESPACE
   pkg/gsDesign/R/gsMethods.R
   pkg/gsDesign/R/gsSurvival.R
   pkg/gsDesign/R/nEvents.R
   pkg/gsDesign/man/nSurvival.Rd
Log:
nSurvival update, including print function

Modified: pkg/gsDesign/NAMESPACE
===================================================================
--- pkg/gsDesign/NAMESPACE	2009-12-18 22:09:48 UTC (rev 231)
+++ pkg/gsDesign/NAMESPACE	2009-12-21 03:05:07 UTC (rev 232)
@@ -4,7 +4,7 @@
 export(ciBinomial, nBinomial, simBinomial, testBinomial, gsBinomialExact)
 export(nSurvival, nEvents)
 export(normalGrid)
-export(plot.gsDesign, plot.gsProbability, print.gsProbability, print.gsDesign)
+export(plot.gsDesign, plot.gsProbability, print.gsProbability, print.gsDesign, print.nSurvival)
 export(sfPower, sfHSD, sfExponential, sfBetaDist, sfLDOF, sfLDPocock, sfPoints, sfLogistic, sfExtremeValue, sfExtremeValue2, sfLinear)
 export(sfCauchy, sfNormal, sfTDist, spendingFunction)
 export(checkScalar, checkVector, checkRange, checkLengths, isInteger)

Modified: pkg/gsDesign/R/gsMethods.R
===================================================================
--- pkg/gsDesign/R/gsMethods.R	2009-12-18 22:09:48 UTC (rev 231)
+++ pkg/gsDesign/R/gsMethods.R	2009-12-21 03:05:07 UTC (rev 232)
@@ -236,6 +236,27 @@
         print(y)
     }
 }
+print.nSurvival <- function(x,y=0,med=F,timeunit="months", ...){
+	if (class(x) != "nSurvival") stop("print.nSurvival: primary argument must have class nSurvival")
+   cat("Two-arm trial with time-to-event outcome with fixed accrual and study duration.\n")
+	cat("Sample size computed using Lachin and Foulkes (1986) method.\n")
+	cat("Accrual duration ", x$Tr, " ", timeunit, " and minimum follow-up ", x$Ts-x$Tr, " ", 
+       timeunit, ".\n", sep="")
+   cat("Fixed design sample size n=", 2*ceiling(x$n/2), " subjects ", sep="")
+   cat("followed until nEvents=", ceiling(x$nEvents), " events occur to detect\n")
+   if (!med) cat("a reduction from a ", round(x$lambda1,3), " failure rate in the control group to a\n",
+                    "failure rate of ", round(x$lambda2,3), " in the experimental group\n", sep="")
+   else cat("an increase from", round(log(2)/x$lambda1,1), "median time-to-event in the control group\nto",
+            round(log(2)/x$lambda2,1), "in the experimental group\n")
+   cat("(hazard ratio =", round(x$lambda2/x$lambda1,3), ") with ", (1-x$beta)*100, "% power and ",
+       x$sided, "-sided Type I error =", 100*x$alpha, "%.\n", sep="")
+	if (class(y) == "gsDesign")
+	{	cat("The total sample size required for the group sequential design is ", 
+        ceiling(x$n * y$n.I[y$k] / y$n.fix /2) *2,".\n", sep="")
+   	cat("The group sequential design analysis plan is given in terms of the number\n",
+       "of events at each analysis below.\n", sep="")
+	}
+}
 
 
 ###
@@ -275,3 +296,4 @@
     }
     cat("\n")
 }
+

Modified: pkg/gsDesign/R/gsSurvival.R
===================================================================
--- pkg/gsDesign/R/gsSurvival.R	2009-12-18 22:09:48 UTC (rev 231)
+++ pkg/gsDesign/R/gsSurvival.R	2009-12-21 03:05:07 UTC (rev 232)
@@ -18,7 +18,7 @@
 ##################################################################################
 
 ############################################################
-## Name: nSurvival.R                                         #
+## Name: nSurvival.R                                       #
 ## Purpose: Calculate sample size for clinical trials      #
 ##          with time-to-event endpoint using LF method    # 
 ## Date: 09/28/2007                                        #
@@ -30,27 +30,35 @@
 ## Update: 1/14/2008                                       #
 ## Reason: add an "sided" argument to indicate one or      #
 ##         two-sided test                                  #
+## Upate: 12/20/2009                                       #
+## Reason: Changed so that output list is consistent with  #
+##         inputs. Also changed lambda.0 to lambda1,       #
+##         lambda.1 to lambda2, and rand.ratio to ratio    #
+##         to be consistent with nBinomial naming          #
+##         conventions.                                    #
+##         Added "nSurvival" as class name for nSurvival   #
+##         output and created print.nSurvival to print it  #
 ############################################################
 
 ###
 # Exported Functions
 ###
 
-"nSurvival" <- function(lambda.0, lambda.1, Ts, Tr,
-        eta = 0, rand.ratio = 1,
-        alpha = 0.05, beta = 0.10, sided = 2,
+"nSurvival" <- function(lambda1=1/12, lambda2=1/24, Ts=24, Tr=12,
+        eta = 0, ratio = 1,
+        alpha = 0.025, beta = 0.10, sided = 1,
         approx = FALSE, type = c("rr", "rd"),
         entry = c("unif", "expo"), gamma = NA)
 {
     ############################################################
     ##                                                         #
     ## calculate sample size                                   #
-    ## lambda.0 -- hazard rate for placebo group               #
-    ## lambda.1 -- hazard rate for treatment group             #
+    ## lambda1 -- hazard rate for placebo group                #
+    ## lambda2 -- hazard rate for treatment group              #
     ## Ts -- study duration                                    #
     ## Tr -- accrual duration                                  #
     ## eta -- exponential dropout rate                         #
-    ## rand.ratio -- randomization ratio (T/P)                 #
+    ## ratio -- randomization ratio (T/P)                      #
     ## alpha -- type I error rate                              #
     ## beta -- type II error rate                              #
     ## sided -- one or two-sided test                          #
@@ -69,19 +77,19 @@
     method <- match(type, c("rr", "rd"))
     accrual <- match(entry, c("unif", "expo")) == 1
     
-    xi0 <- 1 / (1 + rand.ratio)
+    xi0 <- 1 / (1 + ratio)
     xi1 <- 1 - xi0 
     
     if (is.na(method))
     {
-        stop("Only risk ratio or risk difference is valid!")
+        stop("Only rr (risk ratio) or rd (risk difference) is valid!")
     }
     
     # average hazard rate under H_1
-    ave.haz <- lambda.0 * xi0 + lambda.1 * xi1
+    ave.haz <- lambda1 * xi0 + lambda2 * xi1
     
     # vector of hazards: placebo, test, and average 
-    haz <- c(lambda.0, lambda.1, ave.haz)
+    haz <- c(lambda1, lambda2, ave.haz)
     
     prob.e <- sapply(haz, pe, eta = eta, Ts = Ts, Tr = Tr,
             gamma = gamma, unif = accrual)
@@ -89,8 +97,8 @@
     zalpha <- qnorm(1 - alpha / sided)
     zbeta <- qnorm(1 - beta)
     
-    haz.ratio <- log(lambda.0 / lambda.1)
-    haz.diff <- lambda.0 - lambda.1
+    haz.ratio <- log(lambda1 / lambda2)
+    haz.diff <- lambda1 - lambda2
     
     if (method == 1){  # risk ratio
         power <- zalpha/sqrt(prob.e[3]*xi0*xi1) +
@@ -103,14 +111,14 @@
     { # risk difference
         if (approx)
         { # use approximation
-            power <- (zalpha + zbeta) * sqrt((lambda.0^2 * (xi0 * prob.e[1])^(-1) +
-                                lambda.1^2 * (xi1 * prob.e[2])^(-1)))
+            power <- (zalpha + zbeta) * sqrt((lambda1^2 * (xi0 * prob.e[1])^(-1) +
+                                lambda2^2 * (xi1 * prob.e[2])^(-1)))
         }
         else
         { # use variance under H_0 and H_a
             power <- zalpha * (xi0 * xi1 * prob.e[3] / ave.haz^2)^(-1/2) +
-                    zbeta * sqrt((lambda.0^2 * (xi0 * prob.e[1])^(-1) +
-                                        lambda.1^2 * (xi1 * prob.e[2])^(-1)))
+                    zbeta * sqrt((lambda1^2 * (xi0 * prob.e[1])^(-1) +
+                                        lambda2^2 * (xi1 * prob.e[2])^(-1)))
         }
         N <- (power / haz.diff)^2
         E <- N * (xi0 * prob.e[1] + xi1 * prob.e[2])
@@ -118,12 +126,13 @@
     
     # output all the input parameters, including entry type and
     # method, and sample size
-    outd <- list(Method = type, Entry = entry, Sample.size = N,
-            Num.events = E, 
-            Hazard.p = lambda.0, Hazard.t = lambda.1,
-            Dropout = eta, Frac.p = xi0, Frac.t = xi1,
-            Gamma = gamma, Alpha = alpha, Beta = beta, Sided = sided,
-            Study.dura = Ts, Accrual = Tr)
+    outd <- list(type = type, entry = entry, n = N,
+            nEvents = E, 
+            lambda1 = lambda1, lambda2 = lambda2,
+            eta = eta, ratio=ratio, 
+            gamma = gamma, alpha = alpha, beta = beta, sided = sided,
+            Ts = Ts, Tr = Tr)
+    class(outd) <- "nSurvival"
     outd
 }
 

Modified: pkg/gsDesign/R/nEvents.R
===================================================================
--- pkg/gsDesign/R/nEvents.R	2009-12-18 22:09:48 UTC (rev 231)
+++ pkg/gsDesign/R/nEvents.R	2009-12-21 03:05:07 UTC (rev 232)
@@ -1,14 +1,16 @@
-"nEvents" <- function(hr = .6, alpha = .025, beta = .1, ratio = 1, delta0=1, n = 0, tbl = FALSE)
-{   c <- 1 / (1 + ratio)
-    delta <- -c * (log(hr) - log(delta0))
+"nEvents" <- function(hr = .6, alpha = .025, beta = .1, ratio = 1, sided = 1, hr0 =  1, n = 0, tbl = FALSE)
+{   c <- sqrt(ratio) / (1 + ratio)
+    delta <- -c * (log(hr) - log(hr0))
     if (n == 0)
     {   n <- (qnorm(1-alpha)+qnorm(1-beta))^2/delta^2
-        if (tbl) n <- cbind(hr, n = ceiling(n), alpha=alpha, Power=1-beta, delta=delta, ratio=ratio)
+        if (tbl) n <- cbind(hr, n = ceiling(n), alpha=alpha, beta=beta, Power=1-beta, delta=delta, 
+                            ratio=ratio, se=sqrt(1/c/ceiling(n)))
         return(n)
     }
     else
     {   pwr <- pnorm(-(qnorm(1-alpha)-sqrt(n) * delta))
-        if (tbl) pwr <- cbind(hr, n=n, alpha=alpha, Power=pwr, delta=delta, ratio=ratio)
+        if (tbl) pwr <- cbind(hr, n=n, alpha=alpha, beta=1-pwr, Power=pwr, delta=delta,
+                 ratio=ratio, se=sqrt(1/(c*n)))
         return(pwr)
     }
 }

Modified: pkg/gsDesign/man/nSurvival.Rd
===================================================================
--- pkg/gsDesign/man/nSurvival.Rd	2009-12-18 22:09:48 UTC (rev 231)
+++ pkg/gsDesign/man/nSurvival.Rd	2009-12-21 03:05:07 UTC (rev 232)
@@ -6,15 +6,15 @@
 }
 
 \usage{
-nSurvival(lambda.0, lambda.1, Ts, Tr, eta = 0, rand.ratio = 1,
-      alpha = 0.05, beta = 0.10, sided = 2, approx = FALSE,
+nSurvival(lambda1=1/12, lambda2=1/24, Ts=24, Tr=12, eta = 0, ratio = 1,
+      alpha = 0.025, beta = 0.10, sided = 1, approx = FALSE,
       type = c("rr", "rd"), entry = c("unif", "expo"), gamma = NA)
 }
 \arguments{
-  \item{lambda.0, lambda.1}{event hazard rate for placebo and treatment
+  \item{lambda1, lambda2}{event hazard rate for placebo and treatment
     group respectively.}
   \item{eta}{equal dropout hazard rate for both groups.}
-  \item{rand.ratio}{randomization ratio between placebo and treatment
+  \item{ratio}{randomization ratio between placebo and treatment
     group. Default is balanced design, i.e., randomization ratio is 1.}
   \item{Ts}{maximum study duration.}
   \item{Tr}{accrual (recruitment) duration.}
@@ -41,7 +41,7 @@
 
   If the logical approx is \code{TRUE}, the variance under alternative
   hypothesis is used to replace the variance under null hypothesis.
-
+The 
   For non-uniform entry. a non-zero value of gamma for exponential entry
   must be supplied. For positive gamma, the entry distribution is
   convex, whereas for negative gamma, the entry distribution is concave.
@@ -49,21 +49,20 @@
 
 \value{
   \code{nSurvival} produces a list with the following component returned:
-  \item{Method}{As input.}
-  \item{Entry}{As input.}
-  \item{Sample.size}{Number of subjects.}
-  \item{Num.events}{Number of events.}
-  \item{Hazard.p, Hazard.t}{hazard rate for placebo and treatment group. As input.}
-%  \item{Hazard.t}{hazard rate for treatment group. As input.}
-  \item{Dropout}{as input.}
-  \item{Frac.p, Frac.t}{randomization proportion for placebo and
-    treatment. As input.}
-  \item{Gamma}{as input.}
-  \item{Alpha}{as input.}
-  \item{Beta}{as input.}
-  \item{Sided}{as input.}
-  \item{Study.dura}{Study duration.}
-  \item{Accrual}{Accrual period.}
+  \item{type}{As input.}
+  \item{entry}{As input.}
+  \item{n}{Sample size required.}
+  \item{nEvents}{Number of events required.}
+  \item{lambda1}{As input.}
+  \item{lambda2}{As input.}
+  \item{eta}{As input.}
+  \item{ratio}{As input.}
+  \item{gamma}{As input.}
+  \item{alpha}{As input.}
+  \item{beta}{As input.}
+  \item{sided}{As input.}
+  \item{Ts}{As input.}
+  \item{Tr}{As input.}
 }
 
 \author{Shanhong Guan \email{shanhong\_guan at merck.com}}
@@ -85,8 +84,9 @@
 # alpha = 0.05 (two-sided)
 # power = 0.9 (default beta=.1)
 
-ss <- nSurvival(lambda.0=.2 , lambda.1=.1, eta = .1, Ts = 2, Tr = .5,
+ss <- nSurvival(lambda1=.2 , lambda2=.1, eta = .1, Ts = 2, Tr = .5,
                 sided=1, alpha=.025)
+ss
 
 #  symmetric, 2-sided design with O'Brien-Fleming-like boundaries
 #  sample size is computed based on a fixed design requiring n=100
@@ -97,9 +97,9 @@
 # power plot
 	plot(x, plottype = 2)
 # total sample size
-   ceiling(x$n.I[x$k] * ss$Sample.size)
+   ceiling(x$n.I[x$k] / 2 * ss$n) * 2
 # number of events at analyses
-   ceiling(ss$Num.events * x$n.I)
+   ceiling(ss$nEvents * x$n.I)
 }
 
 \keyword{design}



More information about the Gsdesign-commits mailing list