mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 11:35:24 +02:00
fix(experiments): mathematically correctly aggregate ratios like ACOS and ROAS before averaging
This commit is contained in:
@@ -149,6 +149,31 @@ function splitPeriods(
|
||||
|
||||
function avgMetric(data: ComputedWeeklyMetrics[], metric: string, durationWeeks: number): number {
|
||||
if (data.length === 0 || durationWeeks <= 0) return 0;
|
||||
|
||||
// For rates and ratios, we must sum the raw absolute components across all included weeks
|
||||
// and THEN calculate the ratio, otherwise averaging percentages yields mathematically incorrect results.
|
||||
if (metric === 'cvr') {
|
||||
const totalUnits = data.reduce((s, w) => s + w.units, 0);
|
||||
const totalSessions = data.reduce((s, w) => s + w.sessions, 0);
|
||||
return totalSessions > 0 ? (totalUnits / totalSessions) * 100 : 0;
|
||||
}
|
||||
if (metric === 'ctr') {
|
||||
const totalClicks = data.reduce((s, w) => s + w.clicks, 0);
|
||||
const totalImpressions = data.reduce((s, w) => s + w.impressions, 0);
|
||||
return totalImpressions > 0 ? (totalClicks / totalImpressions) * 100 : 0;
|
||||
}
|
||||
if (metric === 'roas') {
|
||||
const totalRevenue = data.reduce((s, w) => s + w.revenue, 0);
|
||||
const totalCost = data.reduce((s, w) => s + w.cost, 0);
|
||||
return totalCost > 0 ? totalRevenue / totalCost : 0;
|
||||
}
|
||||
if (metric === 'acos') {
|
||||
const totalRevenue = data.reduce((s, w) => s + w.revenue, 0);
|
||||
const totalCost = data.reduce((s, w) => s + w.cost, 0);
|
||||
return totalRevenue > 0 ? (totalCost / totalRevenue) * 100 : 0;
|
||||
}
|
||||
|
||||
// For absolute quantities (units, revenue, sessions), we sum them and divide by the duration
|
||||
const sum = data.reduce((s, w) => s + getMetricValue(w, metric), 0);
|
||||
return sum / durationWeeks;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user