How it works
Finding drivers
Contribution, price–volume–mix, rate vs mix and the Simpson guard, with worked examples.
A finding says that something changed; a decomposition says where. Every method is exact: the effects add up to the change, and the identity is tested on randomized cases.
Contribution (contribution.v1)
Section titled “Contribution (contribution.v1)”For a total T = Σ xᵢ, the change ΔT = Σ Δxᵢ and each member’s share is Δxᵢ / ΔT. Shares can exceed 100% when members offset each other — in the example, one customer is 108% of the drop because others grew:
Contribution by channel · Revenue fell after March, driven by wholesale
- Revenue 2026-03$44,100 N12
- wholesale−$8,500 N144108% of the change N147
- retail$600 N145−7.6% of the change N148
- Revenue 2026-04$36,200 N11
Both totals are drawn from a broken axis (≈), so the changes show at their own scale. Each change and its share are contribution.v1 facts recomputed by the verifier. The members drawn are all of them: their changes are the decomposition's total, −$7,900 N146.
Price–volume–mix (pvm.v1)
Section titled “Price–volume–mix (pvm.v1)”When price and quantity columns exist, revenue R = Σ pᵢqᵢ splits into
- volume = (Q₁ − Q₀) · P̄₀,
- mix = Q₁ · (Σ sᵢ₁ pᵢ₀ − Σ sᵢ₀ pᵢ₀),
- price = Σ qᵢ₁ (pᵢ₁ − pᵢ₀),
plus separate new, lost and unpriced effects for items present in only one period. Volume + mix + price + new + lost + unpriced = ΔR exactly.
Rate vs mix (ratemix.v1) and the Simpson guard
Section titled “Rate vs mix (ratemix.v1) and the Simpson guard”For a rate r = Σ wᵢ rᵢ (a refund rate, a conversion rate), the change splits into a mix effect (segment weights moved), a rate effect (rates within segments moved), and entering, exiting and unattributed effects. When the overall rate moves against most segment rates, a simpson_risk flag makes the finding tell the segment-level story.
Worked numbers for every method are in docs/specs/analysis-library.md §4 and its tests.