Last active
July 2, 2024 17:16
-
-
Save nathansmith/a291647a8b597a88ed07c81fe69231a1 to your computer and use it in GitHub Desktop.
Parses a numeric list into: mean, median, mode, etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Gets the median for a list of numbers. | |
* | |
* @param {number[]} [listSorted=[]] | |
* @returns {number} | |
*/ | |
const getMedian = (listSorted = []) => { | |
// Get count. | |
const listCount = listSorted.length; | |
// Get middle index. | |
const indexMiddle = Math.floor(listCount / 2); | |
// Get median. | |
let median = listSorted[indexMiddle]; | |
// Even count: YES. | |
if (listCount % 2 === 0) { | |
// Update median. | |
median = (listSorted[indexMiddle - 1] + listSorted[indexMiddle]) / 2; | |
} | |
// Expose number. | |
return median; | |
}; | |
/** | |
* Rounds to two decimal places. | |
* | |
* @param {number} [n=0] | |
* @returns {number} | |
*/ | |
const roundTwoDecimals = (n = 0) => { | |
// Expose number. | |
return Math.round(n * 100) / 100; | |
}; | |
/** | |
* Parses a list of numbers and computes: | |
* | |
* - Mean = Average value. | |
* - Median = Middle value. | |
* - Mode = Most frequent value(s). | |
* - Maximum = Highest value. | |
* - Minimum = Lowest value. | |
* - Range = Diff between maximum and minimum. | |
* - Range interquartile = Diff between Q3 and Q1. | |
* - Standard deviation = Square root of variance. | |
* - Variance = Squared deviation from the mean. | |
* | |
* @param {number[]} [list=[]] | |
* @returns {object} obj | |
* @returns {number} obj.maximum | |
* @returns {number} obj.mean | |
* @returns {number} obj.median | |
* @returns {number} obj.minimum | |
* @returns {number[]} obj.mode | |
* @returns {number} obj.standardDeviation | |
* @returns {number} obj.range | |
* @returns {number} obj.rangeInterquartile | |
* @returns {number} obj.variance | |
*/ | |
const getListStats = (list = []) => { | |
// Get count. | |
const listCount = list.length; | |
// Get sorted list. | |
const listSorted = list.slice().sort((a, b) => a - b); | |
// Get min, max, range. | |
const minimum = listSorted.at(0); | |
const maximum = listSorted.at(-1); | |
const range = maximum - minimum; | |
// Set later. | |
const modeObj = {}; | |
let total = 0; | |
let totalSquares = 0; | |
// Loop through. | |
for (const value of listSorted) { | |
// Increment count. | |
modeObj[value] ||= 0; | |
modeObj[value]++; | |
// Increment total. | |
total += value; | |
totalSquares += Math.pow(value, 2); | |
} | |
// Get mean, median. | |
const mean = total / listCount; | |
const median = getMedian(listSorted); | |
// Get mode. | |
const modeEntries = Object.entries(modeObj).sort((a, b) => b[1] - a[1]); | |
const modeMax = modeEntries[0]?.[1]; | |
const mode = []; | |
// Loop through. | |
for (const [key, value] of modeEntries) { | |
// Equal to max: YES. | |
if (value === modeMax) { | |
// Add to mode. | |
mode.push(parseFloat(key)); | |
} | |
} | |
// Get quartiles. | |
const quartile1 = getMedian(listSorted.slice(0, Math.floor(listCount / 2))); | |
const quartile3 = getMedian(listSorted.slice(Math.ceil(listCount / 2))); | |
const rangeInterquartile = quartile3 - quartile1; | |
// Get variance & deviation. | |
const variance = (totalSquares / listCount) - Math.pow(mean, 2); | |
const standardDeviation = Math.sqrt(variance); | |
// Expose object. | |
return { | |
mean: roundTwoDecimals(mean || 0), | |
median: roundTwoDecimals(median || 0), | |
mode: mode.length ? mode.map(roundTwoDecimals) : [0], | |
maximum: roundTwoDecimals(maximum || 0), | |
minimum: roundTwoDecimals(minimum || 0), | |
range: roundTwoDecimals(range || 0), | |
rangeInterquartile: roundTwoDecimals(rangeInterquartile || 0), | |
standardDeviation: roundTwoDecimals(standardDeviation || 0), | |
variance: roundTwoDecimals(variance || 0), | |
}; | |
}; | |
/* | |
===== | |
NOTE: | |
===== | |
To call this function, pass an array of values like so. | |
You can then use the resulting object however you need. | |
``` | |
// Get list. | |
const listOfNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2]; | |
// Get stats. | |
const listStats = getListStats(listOfNumbers); | |
// Peel apart. | |
const { | |
mean, | |
median, | |
mode, | |
maximum, | |
minimum, | |
range, | |
rangeInterquartile, | |
standardDeviation, | |
variance, | |
} = listStats; | |
``` | |
*/ | |
// Lists of numbers. | |
const list1 = [3, 7, 5, 4, 5, 6, 7, 8, 6, 5]; | |
const list2 = [34, 54, 17, 26, 34, 25, 14, 24, 25, 23]; | |
const list3 = [154, 167, 132, 145, 154, 145, 113, 156, 154, 123]; | |
const list4 = []; | |
// Log results. | |
console.clear(); | |
console.log("===>>> list1", JSON.stringify(getListStats(list1), null, 2)); | |
console.log("===>>> list2", JSON.stringify(getListStats(list2), null, 2)); | |
console.log("===>>> list3", JSON.stringify(getListStats(list3), null, 2)); | |
console.log("===>>> list4", JSON.stringify(getListStats(list4), null, 2)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment