feat: explain income dispersion within comparable sample groups
This commit is contained in:
@@ -110,3 +110,24 @@ export function groupIncome(points: IncomePoint[], splitModels = true) {
|
||||
}
|
||||
return [...groups.entries()].map(([key, group]) => ({ key, ...group, stats: describeIncome(group.points.map((point) => point.value))! }));
|
||||
}
|
||||
|
||||
/** Compare descriptive statistics only within the same provider and delivery model. */
|
||||
export function compareIncomeGroups(groups: ReturnType<typeof groupIncome>) {
|
||||
const buckets = new Map<string, typeof groups>();
|
||||
for (const group of groups) {
|
||||
if (group.stats.n < 3 || group.stats.cv === null || group.stats.largestRemovalDrop === null ||
|
||||
group.model === "全部收费模式" || group.model === "收费模式未核验") continue;
|
||||
const key = JSON.stringify([group.provider, group.model]);
|
||||
const bucket = buckets.get(key) ?? [];
|
||||
bucket.push(group);
|
||||
buckets.set(key, bucket);
|
||||
}
|
||||
return [...buckets.entries()].flatMap(([key, rows]) => {
|
||||
if (rows.length < 2) return [];
|
||||
const byCV = [...rows].sort((a, b) => a.stats.cv! - b.stats.cv! || a.key.localeCompare(b.key));
|
||||
const bySensitivity = [...rows].sort((a, b) => a.stats.largestRemovalDrop! - b.stats.largestRemovalDrop! || a.key.localeCompare(b.key));
|
||||
return [{ key, provider: rows[0].provider, model: rows[0].model,
|
||||
leastDispersed: byCV[0], mostDispersed: byCV[byCV.length - 1],
|
||||
leastSensitive: bySensitivity[0], mostSensitive: bySensitivity[bySensitivity.length - 1] }];
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user