To Daily States

Convert the eventstream into daily lifecycle-state events.

Each path is expanded to one row per calendar day from its first event to max_dormant_days days after its last event. Every row is labelled with one of six engagement states.

Active days: new — first-ever active day for this path current — active within the past 7 days reactivated — active 8-30 days ago, not in the last 7 resurrected — last active more than 30 days ago

Inactive days: at_risk_wau — was active within the past 7 days at_risk_mau — was active 8-30 days ago dormant — was last active more than 30 days ago

Usage

stream.to_daily_states()
stream.to_daily_states(active_events=["purchase", "add_to_cart"], max_dormant_days=60)

How it works

This processor changes what a "step" in a path means. Normally the next event in a path is the next thing the user did, whenever that was. After to_daily_states, every path has exactly one event per calendar day — the user's engagement state on that day — so consecutive steps are consecutive days and the gaps become visible as events in their own right.

Before — one user, active on two days:

user_ideventtimestamp
u1login2024-01-01
u1login2024-01-03
stream.to_daily_states()

After — one row per day, labelled with that day's state:

user_ideventtimestamp
u1new2024-01-01
u1at_risk_wau2024-01-02
u1current2024-01-03

The first-ever active day is new; 2 January has no activity but the user was active within the last 7 days, so it is at_risk_wau; on 3 January the user is active again and recently seen, so current.

Rows keep being generated for max_dormant_days after the path's last event, so you can see a path decay through at_risk_wauat_risk_maudormant without it silently disappearing from the data. That tail is capped at the last day present in the dataset, so paths active near the end of your observation window get fewer trailing rows than older ones — worth remembering before comparing state distributions across cohorts.

Pass active_events to decide what counts as activity: with active_events=["purchase"], a user who browses daily but never buys still decays to dormant.

Because the output is an ordinary eventstream whose events are states, every tool works on it unchanged — a Transition Graph becomes a state-transition diagram, and a Step Sankey becomes a retention flow.

Parameters

ParameterTypeDescription
active_eventslist of str, optionalEvents that count as "activity". If omitted, any event counts.
max_dormant_daysint, default 30Days after a path's last event to continue generating state rows. Capped at the last day present in the dataset, so paths active near the end of the observation window get fewer trailing rows.
aggdict, optionalPer-column aggregation overrides (e.g. {"revenue": "sum"}).
path_colstr, optionalOverride the path ID column.
event_colstr, optionalOverride the event column.