Approach summary:Use decomposition: revenue = price × quantity. At transaction level, decompose change in total revenue between period A and B into price-driven and volume-driven components using an index decomposition (Laspeyres/Paasche) and complement with a regression/DID for causal inference and CIs.1) Simple index decomposition (transparent, fast)Let R_t = Σ_i p_{i,t} q_{i,t}. Change ΔR = R_B − R_A.Laspeyres (weights = quantities in A) decomposes:Price effect ≈ Σ_i (p_{i,B} − p_{i,A}) q_{i,A}Volume effect ≈ Σ_i p_{i,A} (q_{i,B} − q_{i,A})You can use the midpoint (Fisher) or average weights to reduce bias:Price effect = Σ_i (p_{i,B} − p_{i,A}) * (q_{i,A}+q_{i,B})/2Volume effect = Σ_i (q_{i,B} − q_{i,A}) * (p_{i,A}+p_{i,B})/22) Regression-based decomposition (controls, statistical inference)Run transaction-level model: log(revenue) = log(price) + log(quantity) so equivalently:log(p_{it}) and log(q_{it}) enter additively. Fit:log(rev_{it}) = α + β_p log(p_{it}) + β_q log(q_{it}) + X_{it}γ + ε_{it}Use fixed effects (item, customer, time) to control confounding. Predict counterfactual revenue in B holding prices at A to estimate volume-only effect and vice versa.3) Causal checks and uncertainty- If prices may be endogenous (e.g., targeted price changes), use instrument (cost shocks) or difference-in-differences comparing unaffected control SKUs/regions.- Bootstrap the decomposition to get CIs.- Validate by aggregating model predictions to match observed totals.Python sketch for index decomposition:python
import pandas as pd
df = pd.read_csv('transactions.csv') # cols: sku, period, price, qty
agg = df.groupby(['sku','period']).agg({'price':'mean','qty':'sum'}).unstack()
pA = agg['price','A']; pB = agg['price','B']
qA = agg['qty','A']; qB = agg['qty','B']
price_effect = ((pB - pA) * (qA+qB)/2).sum()
volume_effect = ((qB - qA) * (pA+pB)/2).sum()
When to use which:- Use index decomposition for a clear, explainable breakdown.- Use regression/IV/DID for causal attribution and confidence intervals.Edge cases: new/discontinued SKUs, promotions, returns; handle by mapping missing periods to zero, segmenting analysis, or using average weights.