AHR: computes AHR under NPH assumptions and (stratified) populations
Source:vignettes/usage_AHR.Rmd
usage_AHR.RmdIntroduction of AHR()
AHR() provides a geometric average hazard ratio under various non-proportional hazards assumptions for either single or multiple strata studies. The piecewise exponential distribution allows a simple method to specify a distribution and enrollment pattern where the enrollment, failure and dropout rates changes over time.
Usage of AHR()
Example 1: Un-stratified population
enrollRates <- tibble(Stratum = "All",
duration = c(2, 10, 4, 4, 8),
rate = c(5, 10, 0, 3, 6))
failRates <- tibble(Stratum = "All",
duration = 1,
failRate = c(.1, .2, .3, .4),
hr = c(.9, .75, .8, .6),
dropoutRate = .001)
AHR(enrollRates = enrollRates, failRates = failRates, totalDuration = c(15, 30))## # A tibble: 2 × 5
## Time AHR Events info info0
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 15 0.694 91.0 22.6 22.7
## 2 30 0.685 154. 37.9 38.6
Example 2: Stratified population
enrollRates <- tibble(Stratum = c(rep("Low", 2), rep("High", 3)),
duration = c(2, 10, 4, 4, 8),
rate = c(5, 10, 0, 3, 6))
failRates <- tibble(Stratum = c(rep("Low", 2), rep("High", 2)),
duration = 1,
failRate = c(.1, .2, .3, .4),
hr = c(.9, .75, .8, .6),
dropoutRate = .001)
AHR(enrollRates = enrollRates, failRates = failRates, totalDuration = c(15, 30))## # A tibble: 2 × 5
## Time AHR Events info info0
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 15 0.733 113. 28.1 28.3
## 2 30 0.718 166. 41.3 41.5
Inner Logic of AHR()
Let’s take the un-stratified population as an example, where the enrollment rate, failure rates and dropout rates are
enrollRates <- tibble(Stratum = "All",
duration = c(2, 10, 4),
rate = c(5, 10, 0))
failRates <- tibble(Stratum = "All",
duration = 1,
failRate = c(.1, .2),
hr = c(.9, .75),
dropoutRate = .001)
ratio <- 2
totalDuration <- 30Step 1: compute proportion in each group
Qe <- ratio / (1 + ratio)
Qc <- 1 - Qe## The proportion of the experimental arm is 0.6666667
## The proportion of the control arm is 0.3333333
To compute the expected events over different treatment group, stratum and time period, we iterate over totalDuration and Strata. Since in this example, we only have one analysis time (totalDuration = 30) and one stratum (Stratum = "All"), we only iterate once. In one has multiple analysis time and strata, one can use a for loop and bind the results by row.
td <- totalDuration
s <- "All"Step 2: subset the enrollment rates and failure rates by stratum.
Step 3: we calculate the enrollment rates in experimental arm and control arm, respectively.
Step 4: we update the failure rate in the control and experimental arm.
Step 5: we calculate the expected number of events in the control and experimental by eEvents_df().
events_c <- eEvents_df(enrollRates = enroll_c, failRates = fail_c, totalDuration = td, simple = FALSE)
events_e <- eEvents_df(enrollRates = enroll_e, failRates = fail_e, totalDuration = td, simple = FALSE)## The expected number of events in the control arm is
## # A tibble: 3 × 3
## t failRate Events
## <dbl> <dbl> <dbl>
## 1 0 0.1 3.49
## 2 1 0.2 30.6
## 3 2 0.2 1.98
## The expected number of events in the experimental arm is
## # A tibble: 3 × 3
## t failRate Events
## <dbl> <dbl> <dbl>
## 1 0 0.09 6.31
## 2 1 0.15 57.2
## 3 2 0.15 6.86
Here the t column is the start of period, the failRate column is the failure rate during the period, and the Events column is the expected events during the period.
Step 6: we combine the results together and output it.
# combine control and experimental
events <- rbind(events_c %>% mutate(Treatment = "Control"),
events_e %>% mutate(Treatment = "Experimental")) %>%
arrange(t, Treatment) %>%
ungroup() %>%
# recompute HR, events, info by period
group_by(t) %>%
summarize(Stratum = s,
info = (sum(1 / Events))^(-1),
Events = sum(Events),
HR = last(failRate) / first(failRate)) %>%
# compute info0
mutate(Time = td,
lnhr = log(HR),
info0 = Events * Qc * Qe) %>%
ungroup() %>%
group_by(Time, Stratum, HR) %>%
summarize(t = min(t),
Events = sum(Events),
info0 = sum(info0),
info = sum(info)) %>%
# pool time period together
group_by(Time) %>%
summarize(AHR = exp(sum(log(HR) * Events) / sum(Events)),
Events = sum(Events),
info = sum(info),
info0 = sum(info0))## The overall expected number of events over the time is
## # A tibble: 1 × 5
## Time AHR Events info info0
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 30 0.763 106. 23.7 23.6
Please note that, in the output, the info column is based on the following input.
enrollRates <- tibble(Stratum = "All",
duration = c(2, 10, 4),
rate = c(5, 10, 0))
failRates <- tibble(Stratum = "All",
duration = 1,
failRate = c(.1, .2),
hr = c(.9, .75),
dropoutRate = .001)If the alternative hypothesis \(H_1\) is \[
\text{hr}
=
\left\{
\begin{array}{ll}
0.9 & \text{for the first 1 month} \\
0.75 & \text{afterwards},
\end{array}
\right.
\] then info = info1, where info1 is the statistical information under \(H_1\). But notice that the above enrollRates and failRates is not always the \(H_1\), so we call it as info, rather than info1.