The objective is to estimate Weibull event-free survival (EFS) distributions for two treatment arms using the reported landmark EFS rates at 18 and 24 months, together with a reported hazard ratio of 0.71.
Because the median EFS is reported for Arm 2 but not for Arm 1, the fitted joint model is used to estimate the Arm 1 median EFS.
Main conclusion: under the joint Weibull
proportional hazards model with fixed HR = 0.71, the
estimated median
EFS for Arm 1 is 54.5 months.
The reported Arm 2 median EFS is used as an external check on whether the model-based estimates are reasonable.
We consider two arms with reported EFS rates at 18 and 24 months.
dat <- data.frame(
arm = c("Arm 1", "Arm 1", "Arm 2", "Arm 2"),
x = c(1, 1, 0, 0),
time = c(18, 24, 18, 24),
surv = c(0.73, 0.67, 0.64, 0.59)
)
HR <- 0.71
Here, x = 1 denotes Arm 1 and x = 0 denotes
Arm 2. Arm 2 is treated as the baseline arm.
The hazard ratio is interpreted as
\[ HR = \frac{h_{\text{Arm 1}}(t)}{h_{\text{Arm 2}}(t)} = 0.71. \]
This direction is consistent with the observed landmark EFS rates, since Arm 1 has better EFS than Arm 2.
| Arm | Time (months) | Observed EFS |
|---|---|---|
| Arm 1 | 18 | 73% |
| Arm 1 | 24 | 67% |
| Arm 2 | 18 | 64% |
| Arm 2 | 24 | 59% |
Under a Weibull proportional hazards model,
\[ S(t \mid x) = \exp\left\{ -\exp(\beta x) \left(\frac{t}{\lambda_0}\right)^k \right\}, \]
where
\[ \beta = \log(HR), \]
\(k\) is the common Weibull shape parameter, and \(\lambda_0\) is the Weibull scale parameter for Arm 2.
Taking the transformation \(\log\{-\log S(t)\}\),
\[ \log\{-\log S(t \mid x)\} = \alpha + k \log(t) + \beta x, \]
where
\[ \alpha = -k \log(\lambda_0). \]
Because the hazard ratio is fixed at 0.71, \(\beta\) is fixed. Therefore, define
\[ y^* = \log\{-\log S(t \mid x)\} - \beta x. \]
Then estimate \(\alpha\) and \(k\) from
\[ y^* = \alpha + k \log(t). \]
There are four reported landmark EFS rates but only two unknown model
parameters, \(\alpha\) and \(k\), after fixing the hazard ratio. An
exact solution would require all four transformed observations to fall
exactly on the same Weibull PH curve. In practice, this is unlikely
because the rates are rounded and the hazard ratio is estimated from
fuller trial information. Therefore, \(\alpha\) and \(k\) are estimated by least squares,
choosing the Weibull PH curve that best matches all four landmark rates
while respecting the fixed hazard ratio. The R function
lm() is used below only as a convenient way to perform this
least-squares calculation.
After estimating \(\alpha\) and \(k\),
\[ \lambda_0 = \exp\left(-\frac{\alpha}{k}\right). \]
The Arm-specific Weibull scale parameters are
\[ \lambda_{\text{Arm 2}} = \lambda_0, \]
\[ \lambda_{\text{Arm 1}} = \lambda_0 HR^{-1/k}. \]
The Arm-specific median EFS is
\[ m_x = \lambda_x \{\log(2)\}^{1/k}. \]
dat$y <- log(-log(dat$surv))
dat$log_time <- log(dat$time)
beta <- log(HR)
## Least-squares estimates of alpha and k after the Weibull PH transformation
fit <- lm(I(y - beta * x) ~ log_time, data = dat)
alpha_hat <- coef(fit)[["(Intercept)"]]
shape_hat <- coef(fit)[["log_time"]]
lambda_arm2 <- exp(-alpha_hat / shape_hat)
lambda_arm1 <- lambda_arm2 * HR^(-1 / shape_hat)
median_arm2 <- lambda_arm2 * (log(2))^(1 / shape_hat)
median_arm1 <- lambda_arm1 * (log(2))^(1 / shape_hat)
dat$fitted_surv <- exp(
-exp(alpha_hat + shape_hat * dat$log_time + beta * dat$x)
)
The following table summarizes the fitted model parameters and median EFS estimates from the joint Weibull PH model.
| Quantity | Estimate |
|---|---|
| Fixed HR: Arm 1 vs Arm 2 | 0.710 |
| Common Weibull shape | 0.710 |
| Scale parameter: Arm 1 | 91.300 |
| Scale parameter: Arm 2 | 56.356 |
| Median EFS: Arm 1 | 54.481 |
| Median EFS: Arm 2 | 33.629 |
The following code can be used to generate EFS times from the fitted Weibull distributions for each arm. This code is shown for implementation only and is not executed in this document.
## Estimated parameters from the joint Weibull PH model
shape <- shape_hat
scale_arm1 <- lambda_arm1
scale_arm2 <- lambda_arm2
## Example sample size per arm
n_arm1 <- 1000
n_arm2 <- 1000
set.seed(123)
efs_arm1 <- rweibull(
n = n_arm1,
shape = shape,
scale = scale_arm1
)
efs_arm2 <- rweibull(
n = n_arm2,
shape = shape,
scale = scale_arm2
)
sim_dat <- data.frame(
arm = rep(c("Arm 1", "Arm 2"), times = c(n_arm1, n_arm2)),
efs_time = c(efs_arm1, efs_arm2)
)
| Arm | Time (months) | Observed EFS | Fitted EFS |
|---|---|---|---|
| Arm 1 | 18 | 73% | 72.9% |
| Arm 1 | 24 | 67% | 67.9% |
| Arm 2 | 18 | 64% | 64.1% |
| Arm 2 | 24 | 59% | 58% |
The reported median EFS for Arm 2 is 32.8 months, with 95% CI 27.9 months to not reached (NR).
| Quantity | Value |
|---|---|
| Reported median EFS: Arm 2 | 32.8 months |
| Reported 95% CI lower bound: Arm 2 | 27.9 months |
| Reported 95% CI upper bound: Arm 2 | NR |
| Fitted median EFS: Arm 2 | 33.6 months |
| Fitted median EFS: Arm 1 | 54.5 months |
Under the joint Weibull proportional hazards model with fixed \(HR = 0.71\), the fitted median EFS for Arm 2 (33.6 months) is close to the reported median EFS of 32.8 months. This provides a useful check that the model is broadly compatible with the reported Arm 2 median.
The fitted Arm 1 median EFS (54.5 months) is then estimated from the same joint model. This estimate uses both the observed landmark EFS rates and the reported hazard ratio, rather than relying on the Arm 1 landmark rates alone (see next section).
As a comparison, we can fit a Weibull distribution separately for each arm using only the two landmark EFS rates from that arm. For a Weibull survival function
\[ S(t) = \exp\left\{-\left(\frac{t}{\lambda}\right)^k\right\}, \]
two survival rates at two time points can be used to solve exactly for \(k\) and \(\lambda\).
fit_weibull_two_points <- function(time, surv) {
if (length(time) != 2 || length(surv) != 2) {
stop("Exactly two time points and two survival rates are required.")
}
if (any(time <= 0)) {
stop("Time values must be positive.")
}
if (any(surv <= 0 | surv >= 1)) {
stop("Survival rates must be between 0 and 1.")
}
shape <- diff(log(-log(surv))) / diff(log(time))
scale <- time[1] / (-log(surv[1]))^(1 / shape)
median <- scale * (log(2))^(1 / shape)
data.frame(
shape = shape,
scale = scale,
median = median
)
}
naive_arm1 <- fit_weibull_two_points(
time = dat$time[dat$arm == "Arm 1"],
surv = dat$surv[dat$arm == "Arm 1"]
)
naive_arm2 <- fit_weibull_two_points(
time = dat$time[dat$arm == "Arm 2"],
surv = dat$surv[dat$arm == "Arm 2"]
)
naive_result <- rbind(
data.frame(Arm = "Arm 1", naive_arm1),
data.frame(Arm = "Arm 2", naive_arm2)
)
| Arm | Naive Weibull shape | Naive Weibull scale | Naive median EFS |
|---|---|---|---|
| Arm 1 | 0.838 | 71.550 | 46.196 |
| Arm 2 | 0.582 | 71.992 | 38.353 |
| Quantity | Value |
|---|---|
| Reported median EFS: Arm 2 | 32.8 months |
| Naive fitted median EFS: Arm 2 | 38.4 months |
| Difference: naive minus reported, Arm 2 | 5.6 months |
| Joint PH fitted median EFS: Arm 2 | 33.6 months |
| Difference: joint minus reported, Arm 2 | 0.8 months |
| Naive fitted median EFS: Arm 1 | 46.2 months |
| Joint PH fitted median EFS: Arm 1 | 54.5 months |
The naive separate Weibull fit for Arm 2 gives a median EFS of 38.4 months, which is notably higher than the reported median EFS of 32.8 months. In contrast, the joint Weibull PH model, which uses the reported hazard ratio together with the landmark EFS rates from both arms, gives an Arm 2 median estimate of 33.6 months, which is much closer to the reported value.
This comparison demonstrates the necessity of modeling the reported hazard ratio and the landmark EFS rates jointly when estimating an unreported median EFS. In this setting, the Arm 1 median is not directly reported, so the joint PH model provides a more coherent estimate by borrowing information across both arms while respecting the observed treatment effect.