Comparing version 2.0.1 to 3.0.0
71
index.js
@@ -0,43 +1,40 @@ | ||
module.exports = function reduce (acc, value) { | ||
//handle when called without initial | ||
if('number' === typeof acc) | ||
return reduce(reduce(null, acc), value) | ||
//set initial if initial was null | ||
else if(null == acc) | ||
return { | ||
mean: value, | ||
sum: value, | ||
sqsum: value*value, | ||
count: 1, | ||
stdev: 0 | ||
} | ||
// | ||
// caluclate simple statistics | ||
// | ||
var sum = acc.sum + value | ||
var count = acc.count + 1 | ||
var sq = value*value | ||
module.exports = Stats | ||
var mean = sum/count | ||
var sqsum = acc.sqsum + sq | ||
function Stats () { | ||
if (!(this instanceof Stats)) return new Stats() | ||
this.sum = 0 | ||
this.sqsum = 0 | ||
this.mean = 0 | ||
this.count = 0 | ||
this.max = null | ||
this.min = null | ||
} | ||
return { | ||
//these values useful output | ||
mean: mean, | ||
stdev: Math.sqrt(sqsum/count - mean*mean), | ||
Stats.prototype = { | ||
value: function (val) { | ||
this.sum += val | ||
this.sqsum += val*val | ||
this.count ++ | ||
this.mean = this.sum / this.count | ||
this.max = | ||
this.max === null ? val | ||
: val > this.max ? val | ||
: this.max | ||
this.min = | ||
this.min === null ? val | ||
: val < this.min ? val | ||
: this.min | ||
return this | ||
}, | ||
get variance () { | ||
return this.sqsum / this.count - (this.mean * this.mean) | ||
}, | ||
get stdev() { | ||
return Math.sqrt(this.variance) | ||
}, | ||
toJSON: function () { | ||
return {mean: this.mean, count: this.count, stdev: this.stdev} | ||
//these values needed to maintain state. | ||
count: count, | ||
sum: sum, | ||
sqsum: sqsum | ||
} | ||
} | ||
{ | ||
"name": "statistics", | ||
"version": "2.0.1", | ||
"version": "3.0.0", | ||
"description": "calculate mean standard deviation in one pass", | ||
@@ -5,0 +5,0 @@ "homepage": "http://github.com/dominictarr/statistics", |
# statistics | ||
calculate mean and standard deviation in one pass. | ||
a reduce function that calculates mean and standard deviation in one pass | ||
I first wrote this module a long long time ago, and i used an object oriented | ||
api. Today I needed to serialize a stats output to JSON, and then later parse it, | ||
and keep using it. Continuing to use an OO api would mean a bunch of glue code, | ||
so I rewrote it as a reduce function. | ||
## example | ||
``` js | ||
var Stats = require('statistics') | ||
var s = Stats() | ||
var stats = require('statistics') | ||
s.value(1).value(2).value(3) | ||
console.log('mean:', s.mean, 'stdev:', s.stdev) | ||
> mean: 2 stdev: 0.86... | ||
console.log([1,2,3].reduce(stats)) | ||
=> { | ||
mean: 2, | ||
stdev: 0.8164965809277263, | ||
count: 3, | ||
sum: 6, | ||
sqsum: 14 | ||
} | ||
``` | ||
you probably only want to have the mean and stdev, the other fields are necessary for the reduce | ||
function however. | ||
It's possible to output values as you go. | ||
Since `stdev` is calculated in one pass, | ||
this has minimal memory commitments so you can take averages of everything. | ||
## functional is better than object oriented | ||
statistics@2 and earlier used an object oriented api, but then I needed to serialize and parse a stats | ||
object and keep using it. That was incredibly easy with a reduce function, but would have meant | ||
a bunch of ugly glue code with OO. | ||
## LICENSE | ||
MIT |
var reduce = require('../') | ||
var tape = require('tape') | ||
, Stats = require ('../') | ||
tape('mean', function (t) { | ||
tape('statistics as reduce', function (t) { | ||
var s = Stats() | ||
s.value(1).value(2) | ||
t.equal(s.mean, 1.5) | ||
t.equal(s.min, 1) | ||
t.equal(s.max, 2) | ||
t.end() | ||
var stats = [1,2,3].reduce(reduce) | ||
}) | ||
t.deepEqual(stats, { | ||
mean: 2, | ||
stdev: Math.sqrt((1*1+2*2+3*3)/3 - 2*2), | ||
tape('stdev', function (t) { | ||
sum: 1+2+3, | ||
count: 3, | ||
sqsum: 1*1+2*2+3*3 | ||
}) | ||
var s = Stats() | ||
s.value(1).value(2).value(3) | ||
t.equal(s.mean, 2) | ||
t.equal(s.min, 1) | ||
t.equal(s.max, 3) | ||
//sum of squares | ||
t.equal(s.sqsum, 1*1+2*2+3*3) | ||
//calculate stdev: (sqsum/n - mean^2) | ||
console.log(stats) | ||
var stdev = Math.sqrt((1*1+2*2+3*3)/3 - 2*2) | ||
t.equal(s.stdev, stdev) | ||
t.deepEqual(s.toJSON(), {mean: 2, count: 3, stdev: stdev}) | ||
t.end() | ||
}) | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2457
38
42