Nothing
## ----setup, include = FALSE---------------------------------------------------
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
## ---- message=FALSE, warning=FALSE--------------------------------------------
library(npsurvSS)
library(dplyr)
library(tidyr)
library(tibble)
library(ggplot2)
## -----------------------------------------------------------------------------
fun_hr <- function(HR, k, range.min, range.max) {
(HR-0.3) / (0.9-0.3) * exp(k*(HR-0.3)) / exp(k*(0.9-0.3)) * (range.max-range.min) + range.min
}
## ---- fig.show='hold'---------------------------------------------------------
HR.vec <- seq(0.3, 0.9, 0.01)
plot(HR.vec, fun_hr(HR=HR.vec, k=5, range.min=0.6, range.max=0.7),
xlab="Hazard ratio",
ylab="d/n ratio",
type="l")
plot(HR.vec, fun_hr(HR=HR.vec, k=0, range.min=6, range.max=24),
xlab="Hazard ratio",
ylab="Control median survival (months)",
type="l")
plot(HR.vec, fun_hr(HR=HR.vec, k=2.3, range.min=12, range.max=48),
xlab="Hazard ratio",
ylab="Accrual duration (months)",
type="l")
## ---- fig.width=5-------------------------------------------------------------
p1.vec <- seq(0.5, 0.7, 0.05)
optimal <- tibble(
p1 = rep(p1.vec, each=length(HR.vec)),
HR = rep(HR.vec, length(p1.vec)),
accr_time = fun_hr(HR=HR, k=2.3, range.min=12, range.max=48),
d = (qnorm(0.975)+qnorm(0.9))^2/0.5/0.5/log(HR)^2, # schoenfeld 1981
n = d / fun_hr(HR, k=5, range.min=0.6, range.max=0.7),
m = fun_hr(HR=HR, k=0, range.min=6, range.max=24),
total_time = 0,
power=0,
events0=0,
events1=0
)
## -----------------------------------------------------------------------------
R <- dim(optimal)[1]
for (r in 1:R) {
# scenario specific parameters
p1 <- optimal$p1[r]
HR <- optimal$HR[r]
accr_time <- optimal$accr_time[r]
d <- optimal$d[r]
n <- optimal$n[r]
m <- optimal$m[r]
# create arm objects
arm0 <- create_arm(size=n*(1-p1),
accr_time=accr_time,
accr_interval=accr_time*c(0,0.25,0.5,1), # piecewise-uniform accrual
accr_param=c(0.05,0.25,0.7),
surv_scale=per2haz(m),
loss_scale=per2haz(m)*0.05,
follow_time=12)
arm1 <- create_arm(size=n*p1,
accr_time=accr_time,
accr_interval=accr_time*c(0,0.25,0.5,1),
accr_param=c(0.05,0.25,0.7),
surv_scale=per2haz(m/HR),
loss_scale=arm0$loss_scale,
follow_time=12)
# update total_time and follow_time
duration <- exp_duration(arm0, arm1, d=d)
arm0$total_time <- duration
arm0$follow_time <- duration - arm0$accr_time
arm1$total_time <- duration
arm1$follow_time <- duration - arm1$accr_time
# record results
optimal$total_time[r] <- duration
optimal$power[r] <- power_two_arm(arm0, arm1)
optimal$events0[r] <- exp_events(arm0)
optimal$events1[r] <- exp_events(arm1)
}
head(optimal, 5)
## ---- fig.width=4-------------------------------------------------------------
group_by(optimal, HR) %>%
filter(power==max(power)) %>% # identify p1 that maximizes power
mutate(eprop=events1/d) %>%
select(HR, p1, eprop) %>%
gather(category, prop, 2:3) %>%
mutate(category=ifelse(category=="p1", "Patients", "Events")) %>%
ggplot(aes(x=HR,y=prop)) +
geom_line(aes(col=category, lty=category), lwd=0.8) +
labs(x="Hazard ratio",
y="Proportion contributed by active arm",
col="",
lty="")
## -----------------------------------------------------------------------------
p1.vec <- c(0.5, 3/5, 2/3)
HR.vec <- seq(0.3, 0.9, 0.05)
fixed <- tibble(
p1 = rep(p1.vec, each=length(HR.vec)),
HR = rep(HR.vec, length(p1.vec)),
accr_time = fun_hr(HR=HR, k=2.3, range.min=12, range.max=48),
d = (qnorm(0.975)+qnorm(0.9))^2/0.5/0.5/log(HR)^2, # schoenfeld 1981
n = d / fun_hr(HR, k=5, range.min=0.6, range.max=0.7),
m = fun_hr(HR=HR, k=0, range.min=6, range.max=24),
ed = 0, # power, schoenfeld
mu = 0, # power, recommended asymptotic approximation
mu_b = 0, # power, block randomization
mu_s = 0 # power, simple randomization
)
## -----------------------------------------------------------------------------
R <- dim(fixed)[1]
for (r in 1:R) {
# scenario specific parameters
p1 <- fixed$p1[r]
HR <- fixed$HR[r]
accr_time <- fixed$accr_time[r]
d <- fixed$d[r]
n <- fixed$n[r]
m <- fixed$m[r]
# create arm objects
arm0 <- create_arm(size=n*(1-p1),
accr_time=accr_time,
accr_interval=accr_time*c(0,0.25,0.5,1), # piecewise-uniform accrual
accr_param=c(0.05,0.25,0.7),
surv_scale=per2haz(m),
loss_scale=per2haz(m)*0.05,
follow_time=12)
arm1 <- create_arm(size=n*p1,
accr_time=accr_time,
accr_interval=accr_time*c(0,0.25,0.5,1),
accr_param=c(0.05,0.25,0.7),
surv_scale=per2haz(m/HR),
loss_scale=arm0$loss_scale,
follow_time=12)
# update total_time and follow_time
duration <- exp_duration(arm0, arm1, d=d)
arm0$total_time <- duration
arm0$follow_time <- duration - arm0$accr_time
arm1$total_time <- duration
arm1$follow_time <- duration - arm1$accr_time
# record results
fixed$ed[r] <- power_two_arm(arm0, arm1,
test=list(test="weighted logrank",
mean.approx="event driven"))
fixed$mu[r] <- power_two_arm(arm0, arm1)
fixed$mu_b[r] <- power_two_arm(arm0, arm1,
test=list(test="weighted logrank",
var.approx="block"))
fixed$mu_s[r] <- power_two_arm(arm0, arm1,
test=list(test="weighted logrank",
var.approx="simple"))
}
## ---- fig.width=6-------------------------------------------------------------
gather(fixed, key="approximation", value="power", 7:10) %>%
ggplot(aes(x=HR, y=power)) +
geom_line(aes(col=approximation, lty=approximation)) +
facet_wrap(~round(p1,2)) +
labs(x="Hazard ratio",
y="Power",
col="",
lty="")
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.