[R-pkgs] PwrGSD

Grant Izmirlian izmirlian at nih.gov
Tue Jan 8 20:33:13 CET 2008

Hello List:

Please find uploaded to CRAN a new package, PwrGSD

The package is intended for the design and analysis of group sequential trials
There are two main functions, 
(1) GrpSeqBnds: computes group sequential stopping boundaries for interim
      analysis of a sequential trial based upon a normally distributed test 
      statistic. This can be done via the Lan-Demets procedure with 
      Obrien-Fleming, Pocock or Wang-Tsiatis spending. This can also be
      done via boundaries created to correspond with the stochastic 
      curtailment procedure.  

(2) PwrGSD (same as the package name) which computes operating 
      characteristics such as power, expected duration, weighted avergage 
      relative risks at the boundaries among other things, that correspond to 
      a user supplied hypothetical two arm trial under a user supplied choice
      of monitoring scheme and choice of test statistic within the weighted 
      log-rank class of test statistics. Computations are done either via 
      aysmptotic methods or via simulation.  Note:  another feature is the 
      flexible provision for time dependent non-compliance.  

      The function has a nice calling interface based upon the specification
      of boundary methods via functional forms.  There are alot of nice
      summarization methods which allow the user to explore the space of
      hypothetical trial scenarios and boundary construction methods, such as 
      a compound object class for linking individuals calls to PwrGSD to 
      components of a list that are linked to an indexing dataframe for 
      reference purpose.

      I appologize for a lengthy note, but attach a quite informative example 

      Best Regards,

      Grant Izmirlian
      Mathematical Statistician
      Division of Cancer Prevention
      US National Cancer Institute
      izmirlig at mail.nih.gov
     Հրանտ Իզմիրլյան
       tlook <- c(7.14, 8.14, 9.14, 10.14, 10.64, 11.15, 12.14, 13.14,
                      14.14, 15.14, 16.14, 17.14, 18.14, 19.14, 20.14)
       t0 <- 0:19      
       h0 <- c(rep(3.73e-04, 2), rep(7.45e-04, 3), rep(1.49e-03, 15))
       rhaz <-c(1, 0.9125, 0.8688, 0.7814, 0.6941, 0.6943, 0.6072, 0.5202,  
                      0.4332, 0.652, 0.6524, 0.6527, 0.653, 0.6534, 0.6537, 
                      0.6541, 0.6544, 0.6547, 0.6551, 0.6554)
	hc <- c(rep(1.05e-02, 2), rep(2.09e-02, 3), rep(4.19e-02, 15))
        hd1B <- c(0.1109, 0.1381, 0.1485, 0.1637, 0.2446, 0.2497, 0)

      test.example <- PwrGSD(
         EfficacyBoundary=LanDemets(alpha=0.05, spending= ObrienFleming),
         RR.Futility = 0.82, sided="<",method="A",accru =7.73, accrat=9818.65,
         tlook =tlook, tcut0 =t0, h0=h0, tcut1=t0, rhaz=rhaz, 
         tcutc0=t0, hc0=hc, tcutc1=t0, hc1=hc, 
         tcutd0B =c(0, 13), hd0B =c(0.04777, 0),
         tcutd1B =0:6, hd1B =hd1B,
         noncompliance =crossover, gradual =TRUE,
         WtFun =c("FH", "SFH", "Ramp"),
         ppar =c(0, 1, 0, 1, 10, 10))

     ## we will construct a variety of alternate hypotheses relative to the
     ## base case specified above

       max.effect <- 0.80 + 0.05*(0:8)
       n.me <- length(max.effect)

     ## we will also vary extent of censoring relative to the base case
     ## specified above

       cens.amt <- 0.75 + 0.25*(0:2)
       n.ca <- length(cens.amt)

     ## we may also wish to compare the Lan-Demets/O'Brien-Fleming efficacy
     ## boundary with a Pocock efficacy boundary

       Eff.bound.choice <- 1:2
       ebc.nms <- c("LanDemets(alpha=0.05, spending=ObrienFleming)",
                    "SC(alpha=0.05, crit=0.90)")
       n.ec <- length(Eff.bound.choice)

     ## The following line creates the indexing dataframe, `descr', with one
     ## line for each possible combination of the selection variables we've
     ## created.

       descr <- 
             cbind(Eff.bound.choice=rep(Eff.bound.choice, each=n.ca*n.me),
                      cens.amt=rep(rep(cens.amt, each=n.me), n.ec),
                      max.effect=rep(max.effect, n.ec*n.ca)))

       descr$Eff.bound.choice <- ebc.nms[descr$Eff.bound.choice]

     ## Now descr contains one row for each combination of the levels of
     ## the user defined selection variables, `Eff.bound.choice',
     ## `max.effect' and `cens.amt'. Keep in mind that the names and number
     ## of these variables is arbitrary. Next we create a skeleton
     ## `cpd.PwrGSD' object with a call to the function `cpd.PwrGSD' with
     ## argument `descr'

       test.example.set <- cpd.PwrGSD(descr)

     ## Now, the newly created object, of class `cpd.PwrGSD', contains
     ## an element `descr', a component `date', the date created
     ## and a component `Elements', an empty list of length equal
     ## to the number of rows in `descr'.  Next we do the computation in
     ## a loop over the rows of `descr'.

       n.descr <- nrow(descr)
       for(k in 1:n.descr){

         ## First, we copy the original call to the current call,
         ## `Elements[[k]]$call'

         test.example.set$Elements[[k]]$call <- test.example$call

         ## Use the efficacy boundary choice in the kth row of `descr'
         ## to set the efficacy boundary choice in the current call

         test.example.set$Elements[[k]]$call$EfficacyBoundary <-

         ## Derive the `rhaz' defined by the selection variable "max.effect"
         ## in the kth row of `descr' and use this to set the `rhaz'
         ## components of the current call

         test.example.set$Elements[[k]]$call$rhaz <-
                                 exp(descr[k,"max.effect"] * log(rhaz))

         ## Derive the censoring components from the selection variable
         ## "cens.amt" in the kth row of `descr' and place that result
         ## into the current call

         test.example.set$Elements[[k]]$call$hc0 <-
         test.example.set$Elements[[k]]$call$hc1 <-
                                    exp(descr[k, "cens.amt"] * log(hc))

         ## Now the current call corresponds exactly to the selection
         ## variable values in row `k' of `descr'. The computation is
         ## done by calling `update'

         test.example.set$Elements[[k]] <-
         cat(k/n.descr, "\r")

       ## We can plot the results -- see the help under `plot.cpd.PwrGSD'

       plot(test.example.set, formula = ~ max.effect | stat * cens.amt,
            subset=(substring(Eff.bound.choice, 1,9)=="LanDemets"))

       plot(test.example.set, formula = ~ max.effect | stat * cens.amt,
            subset=(substring(Eff.bound.choice, 1,2)=="SC"))

       ## Notice the appearance of the selection variable `stat' which was
       ## not defined in the dataset `descr'.

More information about the R-packages mailing list