Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Survival risk sets: keep censored cases until they leave observation

Last updated: 7 Oct 20265 min read
tutorial
AdvancedBy AITrove Editorial

A product-limit survival curve updates at events using the number still at risk immediately before each event time.

Define the clock and event

A specialist queue measures time from ticket assignment to first completed resolution. Some tickets remain open when the reporting window ends; those observations are right-censored rather than resolved at the censoring time. Specify start time, resolution rule, administrative end, timezone and whether reopened tickets count as a new episode. The censoring contract prevents unresolved tickets from being discarded as inconvenient missing outcomes.

Build each risk set

At a distinct event time, divide the number of resolutions by the number of tickets still observed and unresolved immediately beforehand, then multiply survival by one minus that fraction. Censored tickets leave the risk set after contributing observed follow-up. When an event and censoring share a recorded time, state the tie convention; the small program processes events before removals at that time. The curve estimates the probability of remaining unresolved beyond time t under its censoring assumptions. The foundational curve lesson describes the same estimator at a broader level.

Expose tail support

A late curve step can be based on only two tickets. Report the number at risk at decision horizons and avoid extrapolating after follow-up ends. Censoring must be reasonably independent of the event time conditional on the design; tickets transferred to another team because they are difficult violate a casual administrative-censoring story. Compare transfer reasons and censoring frequency by queue. Tail uncertainty needs this support table.

Compare a decision horizon

For a service commitment such as 12 hours, report the unresolved probability at 12 hours with interval and at-risk count, if follow-up supports that horizon. If curves cross, one global test can obscure early and late differences; restricted mean time gives a horizon-based quantity. The project catches an export that records transferred tickets as if they resolved immediately.

Implementation

python
from collections import defaultdict

def unresolved_survival_curve(cases):
    if not cases or any(hours < 0 or event not in (0, 1)
                        for hours, event in cases):
        raise ValueError("valid observed durations required")
    by_time = defaultdict(lambda: [0, 0])
    for hours, event in cases:
        by_time[hours][0 if event else 1] += 1
    at_risk = len(cases)
    survival = 1.0
    steps = []
    for hours in sorted(by_time):
        events, censored = by_time[hours]
        if events:
            survival *= 1 - events / at_risk
            steps.append((hours, survival, at_risk))
        at_risk -= events + censored
    return steps

curve = unresolved_survival_curve([(4, 1), (6, 0), (8, 1), (8, 0)])
assert curve == [(4, 0.75, 4), (8, 0.375, 2)]

Performance and operating cost

Grouping n cases by time is O(n) expected time and O(k) space for k distinct times; sorting times costs O(k log k). The bigger cost is correct episode and censoring records. A mathematically exact curve from misclassified transfers can systematically understate unresolved work.

Common Mistakes

  • Dropping open tickets instead of retaining their observed follow-up.
  • Counting censored tickets as resolved at their last contact.
  • Ignoring how event and censor ties are ordered.
  • Reporting a late survival estimate without the number still at risk.

Read next

Continue the workflow: Competing events: calculate the probability of each first outcome.

ai-data
applied-statistics
Storage details