[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
below.
Best Regards,
Grant Izmirlian
Mathematical Statistician
Division of Cancer Prevention
US National Cancer Institute
1-(301)496-7519
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),
FutilityBoundary=LanDemets(alpha=0.1,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 <-
as.data.frame(
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 <-
parse(text=as.character(descr[k,"Eff.bound.choice"]))[[1]]
## 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]] <-
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