function (x = NULL, k = NULL, test.type = NULL, alpha = NULL,
sided = NULL, astar = NULL, sfu = NULL, sfupar = NULL, sfl = NULL,
sflpar = NULL, r = NULL, usTime = NULL, lsTime = NULL, lambdaC = NULL,
hr = NULL, hr0 = NULL, hr1 = NULL, eta = NULL, etaE = NULL,
gamma = NULL, R = NULL, S = NULL, ratio = NULL, minfup = NULL,
method = NULL, spending = c("information", "calendar"), plannedCalendarTime = NULL,
targetEvents = NULL, maxExtension = NULL, minTimeFromPreviousAnalysis = NULL,
minN = NULL, minFollowUp = NULL, tol = .Machine$double.eps^0.25)
{
spending <- match.arg(spending)
if (!is.null(x)) {
if (!inherits(x, "gsSurv"))
stop("x must be a gsSurv object")
sided_infer <- function(tt) if (tt == 1)
1L
else 2L
if (is.null(k))
k <- x$k
if (is.null(test.type))
test.type <- x$test.type
if (is.null(sided))
sided <- sided_infer(if (!is.null(test.type))
test.type
else x$test.type)
if (is.null(alpha))
alpha <- x$alpha * sided
if (is.null(astar))
astar <- x$astar
if (is.null(sfu))
sfu <- x$upper$sf
if (is.null(sfupar))
sfupar <- x$upper$param
if (is.null(sfl))
sfl <- x$lower$sf
if (is.null(sflpar))
sflpar <- x$lower$param
if (is.null(r))
r <- x$r
if (is.null(lambdaC))
lambdaC <- x$lambdaC
if (is.null(hr))
hr <- x$hr
if (is.null(hr0))
hr0 <- x$hr0
if (is.null(hr1))
hr1 <- x$hr
if (is.null(eta))
eta <- x$etaC
if (is.null(etaE))
etaE <- x$etaE
if (is.null(gamma))
gamma <- x$gamma
if (is.null(R))
R <- x$R
if (is.null(S))
S <- x$S
if (is.null(ratio))
ratio <- x$ratio
if (is.null(minfup))
minfup <- x$minfup
if (is.null(method)) {
method <- if (!is.null(x$method))
x$method
else "LachinFoulkes"
}
beta_design <- x$beta
}
else {
if (is.null(k))
stop("k must be specified when x is not provided")
if (is.null(test.type))
test.type <- 4L
if (is.null(sided))
sided <- 1L
if (is.null(alpha))
alpha <- 0.025
if (is.null(astar))
astar <- 0
if (is.null(sfu))
sfu <- gsDesign::sfHSD
if (is.null(sfupar))
sfupar <- -4
if (is.null(sfl))
sfl <- gsDesign::sfHSD
if (is.null(sflpar))
sflpar <- -2
if (is.null(r))
r <- 18
if (is.null(lambdaC))
lambdaC <- log(2)/6
if (is.null(hr))
hr <- 0.6
if (is.null(hr0))
hr0 <- 1
if (is.null(hr1))
hr1 <- hr
if (is.null(eta))
eta <- 0
if (is.null(ratio))
ratio <- 1
if (is.null(R))
R <- 12
if (is.null(minfup))
minfup <- 18
if (is.null(method))
method <- "LachinFoulkes"
beta_design <- 0.1
}
method <- match.arg(method, c("LachinFoulkes", "Schoenfeld",
"Freedman", "BernsteinLagakos"))
if (is.null(etaE))
etaE <- eta
if (!is.matrix(lambdaC))
lambdaC <- matrix(if (is.vector(lambdaC))
lambdaC
else as.vector(lambdaC))
nstrata <- ncol(lambdaC)
nlambda <- nrow(lambdaC)
etaC <- if (is.matrix(eta))
eta
else matrix(eta, nrow = nlambda, ncol = nstrata)
etaE_mat <- if (is.matrix(etaE))
etaE
else matrix(etaE, nrow = nlambda, ncol = nstrata)
if (!is.matrix(gamma))
gamma <- matrix(gamma)
Qe <- ratio/(1 + ratio)
Qc <- 1 - Qe
if (is.null(plannedCalendarTime) && is.null(targetEvents)) {
if (!is.null(x)) {
plannedCalendarTime <- x$T
}
else {
stop("At least one of plannedCalendarTime or targetEvents must be specified")
}
}
if (is.null(k)) {
if (!is.null(plannedCalendarTime))
k <- length(plannedCalendarTime)
else if (is.matrix(targetEvents))
k <- nrow(targetEvents)
else if (!is.null(targetEvents))
k <- length(targetEvents)
}
if (is.null(k) || k < 1)
stop("Could not determine number of analyses (k)")
recycle_k <- function(p, nm) {
if (is.null(p))
return(rep(NA_real_, k))
if (length(p) == 1)
return(rep(p, k))
if (length(p) == k)
return(p)
stop(paste(nm, "must have length 1 or", k))
}
pct <- recycle_k(plannedCalendarTime, "plannedCalendarTime")
me <- recycle_k(maxExtension, "maxExtension")
mtpa <- recycle_k(minTimeFromPreviousAnalysis, "minTimeFromPreviousAnalysis")
mfu <- recycle_k(minFollowUp, "minFollowUp")
mn <- recycle_k(minN, "minN")
if (is.null(targetEvents)) {
te <- rep(NA_real_, k)
}
else if (is.matrix(targetEvents)) {
if (nrow(targetEvents) != k)
stop("targetEvents matrix must have k rows")
te <- rowSums(targetEvents)
}
else {
te <- recycle_k(targetEvents, "targetEvents")
}
ev_at <- function(t) {
dc <- eEvents(lambda = lambdaC, eta = etaC, gamma = gamma *
Qc, R = R, S = S, T = t, minfup = 0)
de <- eEvents(lambda = lambdaC * hr, eta = etaE_mat,
gamma = gamma * Qe, R = R, S = S, T = t, minfup = 0)
list(eDC = dc$d, eDE = de$d, eNC = dc$n, eNE = de$n,
total_d = sum(dc$d + de$d), total_n = sum(dc$n +
de$n))
}
pct_max <- if (any(!is.na(pct)))
max(pct[!is.na(pct)])
else 0
T_ub <- max(sum(R) * 5, pct_max * 2, 200)
find_t_events <- function(target) {
f <- function(t) ev_at(t)$total_d - target
if (f(T_ub) < 0) {
warning("Target ", round(target), " events may not be achievable")
return(T_ub)
}
if (f(0.001) >= 0)
return(0.001)
uniroot(f, c(0.001, T_ub), tol = tol)$root
}
find_t_enroll <- function(target) {
f <- function(t) ev_at(t)$total_n - target
if (f(T_ub) < 0)
return(T_ub)
if (f(0.001) >= 0)
return(0.001)
uniroot(f, c(0.001, T_ub), tol = tol)$root
}
T_an <- numeric(k)
for (i in seq_len(k)) {
floors <- numeric(0)
if (!is.na(pct[i]))
floors <- c(floors, pct[i])
if (i > 1 && !is.na(mtpa[i]))
floors <- c(floors, T_an[i - 1] + mtpa[i])
if (!is.na(mn[i])) {
t_n <- find_t_enroll(mn[i])
fu <- if (!is.na(mfu[i]))
mfu[i]
else 0
floors <- c(floors, t_n + fu)
}
fl <- if (length(floors) > 0)
max(floors)
else 0.001
if (!is.na(te[i])) {
t_ev <- find_t_events(te[i])
if (t_ev <= fl) {
T_an[i] <- fl
}
else if (!is.na(me[i])) {
T_an[i] <- min(t_ev, fl + me[i])
}
else {
T_an[i] <- t_ev
}
}
else {
T_an[i] <- fl
}
if (!is.na(me[i]) && !is.na(pct[i])) {
T_an[i] <- min(T_an[i], pct[i] + me[i])
}
else if (!is.na(me[i]) && i > 1) {
T_an[i] <- min(T_an[i], T_an[i - 1] + me[i])
}
}
eDC_mat <- eDE_mat <- eNC_mat <- eNE_mat <- NULL
for (i in seq_len(k)) {
ev <- ev_at(T_an[i])
eDC_mat <- rbind(eDC_mat, ev$eDC)
eDE_mat <- rbind(eDE_mat, ev$eDE)
eNC_mat <- rbind(eNC_mat, ev$eNC)
eNE_mat <- rbind(eNE_mat, ev$eNE)
}
total_d <- rowSums(eDC_mat) + rowSums(eDE_mat)
timing <- total_d/max(total_d)
compute_delta_ratio <- function(hr_num, hr_denom) {
if (method == "Freedman") {
delta_num <- (hr_num - 1)/(hr_num + 1/ratio)
delta_den <- (hr_denom - 1)/(hr_denom + 1/ratio)
abs(delta_num)/abs(delta_den)
}
else {
abs(log(hr_num) - log(hr0))/abs(log(hr_denom) - log(hr0))
}
}
if (!is.null(x) && !is.null(x$n.fix)) {
n_fix <- x$n.fix
}
else {
T_final <- T_an[k]
minfup_nfix <- max(0, T_final - sum(R))
n_fix <- nSurv(lambdaC = lambdaC, hr = hr1, hr0 = hr0,
eta = eta, etaE = etaE, gamma = gamma, R = R, S = S,
T = T_final, minfup = minfup_nfix, ratio = ratio,
alpha = alpha, beta = beta_design, sided = sided,
tol = tol, method = method)$d
}
if (spending == "calendar") {
usTime_use <- T_an/max(T_an)
lsTime_use <- usTime_use
}
else {
usTime_use <- usTime
lsTime_use <- lsTime
}
if (k == 1) {
z_alpha <- qnorm(1 - alpha/sided)
theta_design <- (z_alpha + qnorm(1 - beta_design))/sqrt(n_fix)
theta_assumed <- theta_design * compute_delta_ratio(hr,
hr1)
drift <- theta_assumed * sqrt(total_d[1])
power_val <- pnorm(drift - z_alpha)
design <- list(k = 1, test.type = test.type, alpha = alpha/sided,
sided = sided, n.I = total_d[1], n.fix = n_fix, timing = 1,
tol = tol, r = r, upper = list(bound = z_alpha, prob = matrix(c(alpha/sided,
power_val), nrow = 1)), lower = list(bound = -20,
prob = matrix(c(1 - alpha/sided, 1 - power_val),
nrow = 1)), theta = c(0, theta_assumed), en = list(en = total_d[1]),
delta = theta_design, delta0 = log(hr0), delta1 = log(hr1),
astar = astar, beta = 1 - power_val)
class(design) <- "gsDesign"
pwr <- list(upper = list(prob = design$upper$prob), lower = list(prob = design$lower$prob),
en = design$en, theta = design$theta)
}
else {
reuse_bounds <- !is.null(x) && !is.null(x$timing) &&
length(x$timing) == k && isTRUE(all.equal(timing,
x$timing, tolerance = 1e-04))
if (reuse_bounds) {
design <- x
lower_bounds <- x$lower$bound
upper_bounds <- x$upper$bound
}
else {
gs_args <- list(k = k, test.type = test.type, alpha = alpha/sided,
beta = beta_design, astar = astar, n.fix = n_fix,
timing = timing, sfu = sfu, sfupar = sfupar,
sfl = sfl, sflpar = sflpar, tol = tol, delta1 = log(hr1),
delta0 = log(hr0), usTime = usTime_use, lsTime = lsTime_use,
r = r)
design <- do.call(gsDesign::gsDesign, gs_args)
lower_bounds <- design$lower$bound
upper_bounds <- design$upper$bound
}
if (length(lower_bounds) == 0)
lower_bounds <- rep(-20, k)
theta_assumed <- design$delta * compute_delta_ratio(hr,
hr1)
pwr <- gsDesign::gsProbability(k = k, theta = c(0, theta_assumed),
n.I = total_d, a = lower_bounds, b = upper_bounds,
r = r)
}
y <- design
y$n.I <- total_d
y$T <- T_an
y$eDC <- eDC_mat
y$eDE <- eDE_mat
y$eNC <- eNC_mat
y$eNE <- eNE_mat
y$hr <- hr
y$hr0 <- hr0
y$hr1 <- hr1
y$R <- R
y$S <- S
y$minfup <- minfup
y$gamma <- gamma
y$ratio <- ratio
y$lambdaC <- lambdaC
y$etaC <- etaC
y$etaE <- etaE_mat
y$variable <- "Power"
y$sided <- sided
y$tol <- tol
y$method <- method
y$spending <- spending
y$call <- match.call()
y$timing <- timing
y$upper$prob <- pwr$upper$prob
y$lower$prob <- pwr$lower$prob
y$en <- pwr$en
y$theta <- pwr$theta
y$power <- sum(pwr$upper$prob[, 2])
y$beta <- 1 - y$power
class(y) <- c("gsSurv", "gsDesign")
nameR <- nameperiod(cumsum(y$R))
stratnames <- paste("Stratum", seq_len(ncol(y$lambdaC)))
nameS <- if (is.null(y$S))
"0-Inf"
else nameperiod(cumsum(c(y$S, Inf)))
rownames(y$lambdaC) <- nameS
colnames(y$lambdaC) <- stratnames
rownames(y$etaC) <- nameS
colnames(y$etaC) <- stratnames
rownames(y$etaE) <- nameS
colnames(y$etaE) <- stratnames
rownames(y$gamma) <- nameR
colnames(y$gamma) <- stratnames
return(y)
}
<bytecode: 0x55ed0ed24ae8>