diff --git a/common/util/math.ts b/common/util/math.ts
index a255c19f..a89b31e1 100644
--- a/common/util/math.ts
+++ b/common/util/math.ts
@@ -1,3 +1,5 @@
+import { sortBy } from 'lodash'
+
export const logInterpolation = (min: number, max: number, value: number) => {
if (value <= min) return 0
if (value >= max) return 1
@@ -16,4 +18,15 @@ export function normpdf(x: number, mean = 0, variance = 1) {
)
}
-const TAU = Math.PI * 2
+export const TAU = Math.PI * 2
+
+export function median(values: number[]) {
+ if (values.length === 0) return NaN
+
+ const sorted = sortBy(values, (x) => x)
+ const mid = Math.floor(sorted.length / 2)
+ if (sorted.length % 2 === 0) {
+ return (sorted[mid - 1] + sorted[mid]) / 2
+ }
+ return sorted[mid]
+}
diff --git a/web/pages/stats.tsx b/web/pages/stats.tsx
index c73b6821..e7590e98 100644
--- a/web/pages/stats.tsx
+++ b/web/pages/stats.tsx
@@ -157,13 +157,11 @@ export async function getStaticPropz() {
bets?.map((b) => b.userId) ?? [],
comments?.map((c) => c.userId) ?? []
)
- const counts = Object.entries(countBy(userIds))
- const topTenth = sortBy(counts, ([, count]) => count)
- .reverse()
- // Take the top 10% of users, except for the top 2, to avoid outliers.
- .slice(2, counts.length * 0.1)
- const topTenthTotal = sumBy(topTenth, ([_, count]) => count)
- return topTenthTotal
+ const counts = Object.values(countBy(userIds))
+ const sortedCounts = sortBy(counts, (count) => count).reverse()
+ if (sortedCounts.length === 0) return 0
+ const tenthPercentile = sortedCounts[Math.floor(sortedCounts.length * 0.1)]
+ return tenthPercentile
})
const weeklyTopTenthActions = dailyTopTenthActions.map((_, i) => {
const start = Math.max(0, i - 6)
@@ -212,9 +210,11 @@ export async function getStaticPropz() {
weekOnWeekRetention,
weeklyActivationRate,
monthlyRetention,
- dailyTopTenthActions,
- weeklyTopTenthActions,
- monthlyTopTenthActions,
+ topTenthActions: {
+ daily: dailyTopTenthActions,
+ weekly: weeklyTopTenthActions,
+ monthly: monthlyTopTenthActions,
+ },
manaBet: {
daily: dailyManaBet,
weekly: weeklyManaBet,
@@ -237,9 +237,11 @@ export default function Analytics(props: {
weekOnWeekRetention: number[]
monthlyRetention: number[]
weeklyActivationRate: number[]
- dailyTopTenthActions: number[]
- weeklyTopTenthActions: number[]
- monthlyTopTenthActions: number[]
+ topTenthActions: {
+ daily: number[]
+ weekly: number[]
+ monthly: number[]
+ }
manaBet: {
daily: number[]
weekly: number[]
@@ -258,9 +260,11 @@ export default function Analytics(props: {
weekOnWeekRetention: [],
monthlyRetention: [],
weeklyActivationRate: [],
- dailyTopTenthActions: [],
- weeklyTopTenthActions: [],
- monthlyTopTenthActions: [],
+ topTenthActions: {
+ daily: [],
+ weekly: [],
+ monthly: [],
+ },
manaBet: {
daily: [],
weekly: [],
@@ -301,9 +305,11 @@ export function CustomAnalytics(props: {
weekOnWeekRetention: number[]
monthlyRetention: number[]
weeklyActivationRate: number[]
- dailyTopTenthActions: number[]
- weeklyTopTenthActions: number[]
- monthlyTopTenthActions: number[]
+ topTenthActions: {
+ daily: number[]
+ weekly: number[]
+ monthly: number[]
+ }
manaBet: {
daily: number[]
weekly: number[]
@@ -321,9 +327,7 @@ export function CustomAnalytics(props: {
weekOnWeekRetention,
monthlyRetention,
weeklyActivationRate,
- dailyTopTenthActions,
- weeklyTopTenthActions,
- monthlyTopTenthActions,
+ topTenthActions,
manaBet,
} = props
@@ -525,10 +529,10 @@ export function CustomAnalytics(props: {
/>
- From the top 10% of users, how many bets, comments, and markets did they - create? (Excluding top 2 users each day.) + Number of actions (bets, comments, markets created) taken by the tenth + percentile of top users.