#' @param object a coxph object
#' @param data a data-frame or tmerge object with columns tstart, tstop, status, an id and the exposure variables
#' @param id a character for the subject id
#' @param times a numeric vector of times (a zero will be added to the start if not included)
#' @returns a data-frame with cumulative and interval-specific survival probabilities
predict_coxph_tv_cond = function(object,data,id,times) {
stopifnot(inherits(object,"coxph"),
inherits(data,"data.frame"),
all(c("tstart","tstop","status",id) %in% names(data)),
is.numeric(times))
if (times[1] != 0) times = c(0,times)
data2 = by(data, data[[id]], function(datai)
## append for the later times
if (max(datai$tstop)>max(times))
datai else rbind(datai,
transform(datai[nrow(datai),],
tstart=tstop,tstop=max(times),status=0))) |>
do.call(what=rbind) |>
## and split the times
survSplit(Surv(tstart,tstop,status)~., data=_, cut=times)
data3 = predict_coxph_tv(object, data2, id)
by(data3, data3[[id]], function(datai) {
## survival and cumulative hazards at the required times
surv = subset(datai, tstop %in% times)$surv
H = c(0,-log(surv)) # padded with H(0)=0
## interval-specific survival for required times
newdata2 = data.frame(id=datai[[id]][1],
tstart=head(times,-1),
tstop=times[-1],
surv,
P=exp(-diff(H)))
names(newdata2)[1] = id
newdata2
}) |> do.call(what=rbind)
}
## Table 8.9
predict_coxph_tv_cond(fit3,data=subset(liver,patient %in% c(1,7)),
id="patient",times=seq(0,360*4,by=360))