Thanks to those who responded! I understand that cumulative incidence is technically undefined at time > max(observed time). However, I'd like to still display the final cumulative incidence in situations like my first example above: max observed time was 4.67 months with many cases after 4 months, so if the risk table only went until 4 months, it wouldn't show the final cumulative incidence at the end of follow-up.
I know the trial dataset is not the best example for this question because max(ttdeath)=24, so I could just use "breaks = seq(0, 24, by = 6)", as one of the responses mentioned. But let's pretend max(ttdeath) was 24.67 and I wanted to display the risk table through time=25.
I was able to come up with a workaround by using conditional logic to replace the missing estimates with max cumulative incidence. It's not the most elegant solution, so other suggestions or improvements to my code are still welcome. Thanks!
# Generate survival/cumulative incidence data
library(ggsurvfit)
cuminc <- survfit2(Surv(ttdeath, death_cr) ~ trt, tidycmprsk::trial) |>
ggcuminc(outcome = "death from cancer")
# Pull maximum cumulative incidence
max_cuminc <- cuminc$data|> group_by(strata) |> summarize(max_cuminc=round((max(estimate))*100))
max_cumincA <- max_cuminc |> filter(strata=='Drug A') |> pull(max_cuminc)
max_cumincB <- max_cuminc |> filter(strata=='Drug B') |> pull(max_cuminc)
# Plot
cuminc +
add_risktable(
risktable_stats =
c("{n.risk}",
"{cum.event}",
#"{round((estimate)*100)}%"), #NA for last estimate
"{case_when(!is.na(estimate) ~ round(estimate*100),
is.na(estimate) & strata=='Drug A' ~ max_cumincA,
is.na(estimate) & strata=='Drug B' ~ max_cumincB)}%"), #workaround
stats_label = c("At Risk",
"Cumulative Events",
"Cumulative Incidence"),
size = 3
) +
scale_ggsurvfit(x_scales = list(breaks = seq(0, 25, by = 5),
limits = c(-1, 26))) #set limits to avoid text cutoff