Zachary R. McCaw
Updated: 2026-10-06
AURMC analyzes outcomes measured repeatedly across time when follow-up may be censored or end prematurely because of a terminal event such as death. It summarizes each group’s outcome experience via the area under its repeated-measures curve, capturing both the magnitude and duration of the outcome. This approach is useful when cumulative experience is more meaningful than the outcome at one time point. Examples may include days alive and out of hospital in heart failure, cumulative glycemic exposure based on serial blood glucose or HbA1c measurements in diabetes, and time alive in tumor response based on response status at successive oncology assessments. For methodological details and an application to days alive and out of hospital, see McCaw ZR, et al. (2026), “Using Days Alive and Out of Hospital as the Study Endpoint in Cardiovascular Heart Failure Clinical Trials”, JACC: Heart Failure, 14(7):103013.
devtools::install_github(repo = 'zrmacc/AURMC')
See the Supplemental Proofs.
The function GenData simulates example data in the format expected by
this package.
library(AURMC)
set.seed(101)
data <- AURMC::GenData(
censoring_rate = 0.5,
death_rate = 0.5,
n = 25,
tau = 4
)
head(data)
## idx time status value
## 1 1 0.0000000 1 0.5524619
## 2 1 1.0000000 1 -0.6749438
## 3 1 2.0000000 1 0.2143595
## 4 1 2.3638814 0 0.3107692
## 5 2 0.0000000 1 0.9170283
## 6 2 0.6309311 2 -0.2232594
The columns are:
idx, the subject identifier.time, the observation time.status, coded 0 for censoring, 1 for a measurement, and 2 for a
terminal event (e.g. death).value, the value of the measurement at the observation time.
Note that:
time = 0 with
status = 1.status = 0 for censoring or status = 2 for a
terminal event.
NA), their last value
is carried forward.
The function Interpolate optionally performs linear interpolation
between measurements to enable more precise area estimation. This step
can be skipped if interpolation is not meaningful for the outcome of
interest, for example the value remains constant between observations.
# Simple example data.
data <- data.frame(
idx = c(1, 1, 2, 2),
status = c(1, 0, 1, 2),
time = c(0, 1, 0, 1),
value = c(0, 1, 0, -1)
)
show(data)
## idx status time value
## 1 1 1 0 0
## 2 1 0 1 1
## 3 2 1 0 0
## 4 2 2 1 -1
grid <- c(0, 0.5, 1.0)
interpolated <- AURMC::Interpolate(
data = data,
grid = grid
)
show(interpolated)
## idx status time value
## 1 1 1 0.0 0.0
## 2 1 1 0.5 0.5
## 3 1 0 1.0 1.0
## 4 2 1 0.0 0.0
## 5 2 1 0.5 -0.5
## 6 2 2 1.0 -1.0
Case where the expected area is zero:
set.seed(101)
data <- AURMC::GenData(
censoring_rate = 0.5,
death_rate = 0.5,
n = 25,
tau = 4
)
AURMC::AURMC(data, tau = 2.0)
## method tau auc se lower upper p
## 1 asymptotic 2 0.009034877 0.2307179 -0.4431639 0.4612337 0.9687629
Case where the expected area is non-zero:
set.seed(101)
data <- AURMC::GenData(
censoring_rate = 0.5,
death_rate = 0.5,
n = 25,
tau = 4,
value_mean = 1.0
)
AURMC::AURMC(data, tau = 2.0)
## method tau auc se lower upper p
## 1 asymptotic 2 1.234052 0.2420008 0.7597394 1.708365 3.4078e-07
Case of no true difference:
set.seed(102)
# Reference arm.
data0 <- AURMC::GenData(
censoring_rate = 0.5,
death_rate = 0.5,
n = 25,
tau = 4,
value_mean = 1.0
)
data0$arm <- 0
# Treatment arm.
data1 <- AURMC::GenData(
censoring_rate = 0.5,
death_rate = 0.5,
n = 25,
tau = 4,
value_mean = 1.0
)
data1$arm <- 1
data1$idx <- max(data0$idx) + data1$idx
# Overall data set.
data <- rbind(data0, data1)
AURMC::CompareAURMCs(data)
## Arm 0:
## method arm tau auc se lower upper p
## 1 asymptotic 0 2.69 1.02 0.239 0.552 1.49 1.95e-05
##
##
## Arm 1:
## method arm tau auc se lower upper p
## 1 asymptotic 1 2.69 1.32 0.263 0.8 1.83 5.6e-07
##
##
## Contrast:
## method stat est se lower upper p
## 1 asymptotic A1-A0 0.295 0.355 -0.402 0.991 0.407
## 2 asymptotic A1/A0 1.290 0.397 0.705 2.360 0.410
Case of a true difference:
set.seed(102)
# Reference arm.
data0 <- AURMC::GenData(
censoring_rate = 0.5,
death_rate = 0.5,
n = 25,
tau = 4,
value_mean = 1.0
)
data0$arm <- 0
# Treatment arm.
data1 <- AURMC::GenData(
censoring_rate = 0.5,
death_rate = 0.5,
n = 25,
tau = 4,
value_mean = 2.0
)
data1$arm <- 1
data1$idx <- max(data0$idx) + data1$idx
# Overall data set.
data <- rbind(data0, data1)
AURMC::CompareAURMCs(data)
## Arm 0:
## method arm tau auc se lower upper p
## 1 asymptotic 0 2.69 1.02 0.239 0.552 1.49 1.95e-05
##
##
## Arm 1:
## method arm tau auc se lower upper p
## 1 asymptotic 1 2.69 2.43 0.413 1.62 3.24 3.99e-09
##
##
## Contrast:
## method stat est se lower upper p
## 1 asymptotic A1-A0 1.41 0.477 0.473 2.34 0.00316
## 2 asymptotic A1/A0 2.38 0.688 1.350 4.19 0.00274