UPDATE-----------------
I have data where one ID can serve as a comparator several times.
This is done by creating a variable to group the treated in variable GROUP
. Assume variable GROUP
, as an example, containing the number of visits to a physician until a therapy is initiated. Thus, ID
4 initiated the therapy after 3 visits. A possible comparator is selected if it also has 3 physician visits but does not initiate the therapy. Therefore, both belong to GROUP == 3
. Note that this could happen on different points in time specified in variable TIME_POINT
. As ID
1 never starts therapy it contributes also a possible comparator observation for someone who initiated therapy after 5 physician visits in GROUP == 5
.
Next, within every value of variable GROUP
, the covariates are collected in a time window before the TIME_POINT
on which an ID
belongs to a GROUP
.
In this minimum example, assume covariates to be balanced using a weight specified in variable WEIGHT
. In addition, the data outside the minimum example has several comparators per GROUP
.
Kept short:
ID
1 is a comparator as it is untreated (TREAT == 0
) and has one event in total.
ID
2, 3, 4, 5 and 6 are different from each other and were treated (TREAT == 1
).
ID
1 therefore contributes to different GROUP
s as a comparator for ID
2, 3, 4, 5 and 6.
ID
1 has one event in total.
Accordingly, the duration of the follow-up time (Variable FOLLOW_UP_TIME
) naturally shortens as value of GROUP
and the associated variable TIME_POINT
increases.
Data:
data <- data.frame(
ID = c(1, 1, 1, 1, 1, 2, 3, 4, 5, 6),
TREAT = c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1),
GROUP = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5),
TIME_POINT = as.Date(c("2019-05-13", "2019-06-01", "2020-03-01", "2021-02-01", "2022-09-01", "2021-02-01", "2021-04-01", "2021-07-01", "2021-01-13", "2021-01-01")),
EVENT_DATE = as.Date(c("2022-10-01", "2022-10-01", "2022-10-01", "2022-10-01", "2022-10-01", "2022-01-03", "2021-10-03", NA, NA, NA)),
END_DATE = as.Date(c("2022-10-01", "2022-10-01", "2022-10-01", "2022-10-01", "2022-10-01", "2022-01-03", "2022-10-03", "2021-10-04", "2021-09-03", "2021-11-02")),
EVENT = c(1, 1, 1, 1, 1, 1, 1, 0, 0, 0),
FOLLOW_UP_TIME = c(1237, 1218, 944, 607, 30, 336, 185, 95, 233, 305),
WEIGHT = c(0.834, 0.543, 0.234, 0.743, 0.323, 1, 1, 1, 1, 1)
)
ID TREAT GROUP TIME_POINT EVENT_DATE END_DATE EVENT FOLLOW_UP_TIME WEIGHT
1 0 1 2019-05-13 2022-10-01 2022-10-01 1 1237 0.834
1 0 2 2019-06-01 2022-10-01 2022-10-01 1 1218 0.543
1 0 3 2020-03-01 2022-10-01 2022-10-01 1 944 0.234
1 0 4 2021-02-01 2022-10-01 2022-10-01 1 607 0.743
1 0 5 2022-09-01 2022-10-01 2022-10-01 1 30 0.323
2 1 1 2021-02-01 2022-01-03 2022-01-03 1 336 1
3 1 2 2021-04-01 2021-10-03 2021-10-03 1 185 1
4 1 3 2021-07-01 <NA> 2021-10-04 0 95 1
5 1 4 2021-01-13 <NA> 2021-09-03 0 233 1
6 1 5 2021-01-01 <NA> 2021-11-02 0 305 1
Example of GROUP == 5
:
ID TREAT GROUP TIME_POINT EVENT_DATE END_DATE EVENT FOLLOW_UP_TIME WEIGHT
1 0 5 2022-09-01 2022-10-01 2022-10-01 1 30 0.323
6 1 5 2021-01-01 <NA> 2021-11-02 0 305 1
Since an ID can occur several times as a comparator, I use bootstrapped standard errors for the cox model and tried to specify the cluster argument to account for the different time points of comparability, specified in variable GROUP
:
library(survival)
library(boot)
r <- 1000
cox_fit <- function(data, indices) {
subset_data <- data[indices, ]
cox_model <- coxph(Surv(FOLLOW_UP_TIME, EVENT) ~ TREAT, data = subset_data, robust = TRUE, weights = WEIGHT, cluster = GROUP)
return(coef(cox_model))
}
set.seed(123)
bootstrap_results <- boot(data = data, statistic = cox_fit, R = r)
print(bootstrap_results, digits = 2)
conf_level <- 0.95
boot_ci <- boot.ci(bootstrap_results, type = c("bca"), conf = conf_level)
boot_ci
Model:
ph <- coxph(Surv(FOLLOW_UP_TIME, EVENT) ~ TREAT, data = data, robust = TRUE, weights = WEIGHT, cluster = GROUP)
> ph
Call:
coxph(formula = Surv(FOLLOW_UP_TIME, EVENT) ~ TREAT, data = data,
weights = WEIGHT, robust = TRUE, cluster = GROUP)
coef exp(coef) se(coef) robust se z p
TREAT 2.053 7.792 1.950 1.396 1.47 0.141
Likelihood ratio test=1.58 on 1 df, p=0.2088
n= 10, number of events= 7
Is the cluster argument sufficient? How to handle such situation where one contributes many times as a comparator since the model assumes 7 events?
TIME_POINT
variable and its relation toFOLLOW_UP_TIME
. The definition ofGROUP
based onTIME_POINT
seems a bit unusual. If you are trying to correct forTIME_POINT
as something like a study-entry time, that might be better handled withTIME_POINT
as a predictor in the model. Also, do you only have 6 individuals with 3 events among them? Or is this just a set of sample data illustrating the situation? $\endgroup$treat == 1
. VariableGROUP
must be used because, for example, 2ID
s can also have differentTIME_POINTS
but belong to the sameGROUP
. Due to the complexity, however, I have left this out. $\endgroup$FOLLOW_UP_TIME
is the difference betweenTIME_POINT
andEVENT_DATE
$\endgroup$ID
s can also have differentTIME_POINTS
but belong to the sameGROUP
." If I understand correctly,GROUP
is a categorization according toTIME_POINT
values; see this page for why that's a bad idea. There are better ways to adjust for differences inTIME_POINT
values, if that's what you want to do. Please provide that information and what's in your previous comments by editing the original question; comments are easy to overlook and can be deleted. $\endgroup$