Create an er_tte specification for a time-to-event plot.
Build the plot by adding layers for survival curves,
censoring markers, risk tables, textual summaries, and model predictions;
render with plot()/print() or er_tte_build().
Arguments
- data
Data frame or tibble containing the observed data.
- time
Event/censoring time (unquoted expression, evaluated in
data). Must be non-negative.- event
Event indicator (unquoted expression, evaluated in
data):TRUE/1for an event,FALSE/0for censoring.- stratify_by
Optional stratification variable (unquoted, bare column name), used as-is. Must be discrete – a numeric column errors. Defaults to
NULL(a single, unstratified curve).- conf_level
Confidence level for the Kaplan-Meier confidence band. Must be strictly between 0 and 1. Defaults to
0.95.
Value
An (empty of layers) plot object of class er_tte, with the
Kaplan-Meier fit already computed on object$km.
Details
er_tte() computes the (single-arm) Kaplan-Meier estimate once, via
survival::survfit(), and stores the fit plus a tidy per-event-time
table (time, n_risk, n_event, n_censor, surv, lower,
upper) on object$km. Layers added afterwards – the curve
(er_tte_add_curve()), censoring marks (er_tte_add_censor()), a
number-at-risk panel (er_tte_add_risktable()), summary annotation
(er_tte_add_summary()), and a parametric model overlay
(er_tte_add_model()) – read from this shared fit rather than
recomputing it (the model layer alone reads from the caller-supplied
model instead, via er_predict_survival()).
Unlike er_plot()/er_vpc(), time/event accept arbitrary
tidy-eval expressions, not just bare column names – time-to-event
data very commonly needs an inline transform to get an event
indicator (e.g. status == 2 for a coded status variable, or
!is.na(progression_date)), and requiring the caller to first
dplyr::mutate() that column into existence would just be
boilerplate. The evaluated time/event vectors are stored as
.er_tte_time/.er_tte_event columns on object$data; their
rlang::as_label()-derived text is kept as object$time$label/
object$event$label for display purposes.
event must evaluate to a logical vector (TRUE = event occurred)
or a numeric vector taking only the values 0 (censored) and 1
(event) – exactly the same binary encoding er_plot() requires of a
response_type = "binary" response.
Optional stratify_by splits the Kaplan-Meier estimate into one curve
per level, via survival::survfit()'s ~ strata formula side. It
must name a discrete/categorical variable – mirroring er_plot()/
er_vpc()'s own stratify_by, a numeric one errors; bin it yourself
first with cut_quantile()/cut_exposure_quantile() and pass the
resulting factor, for full control over bin count/tie-breaking/labels.
Unlike time/event, stratify_by must be a bare column name (not
an arbitrary expression), matching exposure/response/stratify_by
elsewhere in the package. object$km$table gains a strata column
when stratified; object$strata (var/label) mirrors er_vpc()'s
own object$strata.
Examples
library(survival)
lung |>
er_tte(time, status == 2)
#> <er_tte>
#> tte variables:
#> - time: time
#> - event: status == 2
#> kaplan-meier fit (single-arm):
#> - n subjects: 228
#> - n events: 165
#> - median survival: 310
#> plot layers: <none>
#> output built: no
# `lung$sex` is coded numerically (1/2); `stratify_by` requires a
# discrete variable, so convert it to a factor first
lung |>
transform(sex = factor(sex, labels = c("Male", "Female"))) |>
er_tte(time, status == 2, stratify_by = sex)
#> <er_tte>
#> tte variables:
#> - time: time
#> - event: status == 2
#> - stratify_by: sex
#> kaplan-meier fit:
#> - Male: n=138, events=112, median=270
#> - Female: n=90, events=53, median=426
#> plot layers: <none>
#> output built: no