Skip to content

Commit

Permalink
fix(computeStats) #427 Exception thrown when firstQuartile and thirdQ…
Browse files Browse the repository at this point in the history
…uartile are equal (#841)

* fix: [computeStats] change method to calculate first and third quartile to fix #427

* test: [computeStats] add test for edge case mentioned in #427

* refactor: move `calcMedian` out of `computeStats`
  • Loading branch information
LethalPants authored Oct 6, 2020
1 parent 24a31ca commit 9e52d53
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
22 changes: 19 additions & 3 deletions packages/visx-stats/src/util/computeStats.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import { BoxPlot, BinDatum } from '../types';

function calcMedian(dataSet: number[]) {
const half = Math.floor(dataSet.length / 2);
if (dataSet.length % 2) return dataSet[half];
return (dataSet[half - 1] + dataSet[half]) / 2;
}

export default function computeStats(numericalArray: number[]) {
const points = [...numericalArray].sort((a, b) => a - b);
const sampleSize = points.length;
const firstQuartile = points[Math.round(sampleSize / 4)];
const thirdQuartile = points[Math.round((3 * sampleSize) / 4)];

const median = calcMedian(points);

// calculate median of first half i.e. firstQuartile
const lowerHalfLength = Math.floor(sampleSize / 2);
const lowerHalf = points.slice(0, lowerHalfLength);
const firstQuartile = calcMedian(lowerHalf);

// calculate median of first half i.e. secondQuartile
const upperHalfLength = Math.ceil(sampleSize / 2);
const upperHalf = points.slice(upperHalfLength);
const thirdQuartile = calcMedian(upperHalf);
const IQR = thirdQuartile - firstQuartile;

const min = firstQuartile - 1.5 * IQR;
Expand Down Expand Up @@ -38,7 +54,7 @@ export default function computeStats(numericalArray: number[]) {
const boxPlot: BoxPlot = {
min,
firstQuartile,
median: points[Math.round(sampleSize / 2)],
median,
thirdQuartile,
max,
outliers,
Expand Down
7 changes: 7 additions & 0 deletions packages/visx-stats/test/computeStats.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { computeStats } from '../src';

const data = [1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 1];
const edgeCaseData = [10000, 2400, 10000, 10000];

describe('computeStats', () => {
test('it should be defined', () => {
Expand All @@ -12,4 +13,10 @@ describe('computeStats', () => {
expect(stats.boxPlot).toBeDefined();
expect(stats.binData).toBeDefined();
});

test('it should have boxPlot and binData when first and third quartile are equal', () => {
const stats = computeStats(edgeCaseData);
expect(stats.boxPlot).toBeDefined();
expect(stats.binData).toBeDefined();
});
});

0 comments on commit 9e52d53

Please sign in to comment.