{
  "name": "fast-stats",
  "version": "0.0.2",
  "description": "Quickly calculate common statistics on lists of numbers",
  "keywords": [
    "statistics",
    "statistic",
    "gauss",
    "lognormal",
    "normal",
    "mean",
    "median",
    "mode",
    "standard deviation",
    "margin of error",
    "iqr",
    "quartile",
    "inter quartile range"
  ],
  "homepage": "https://github.com/bluesmoon/node-faststats",
  "author": {
    "name": "Philip Tellis",
    "email": "philip@bluesmoon.info",
    "url": "http://bluesmoon.info/"
  },
  "main": "faststats.js",
  "repository": {
    "type": "git",
    "url": "git://github.com/bluesmoon/node-faststats.git"
  },
  "dependencies": {},
  "devDependencies": {},
  "engines": {
    "node": "*"
  },
  "readme": "Fast Statistics\n===============\n\nA NodeJS library to do statistical analysis of numeric datasets.\n\nintroduction\n------------\n\nWhen doing statistical analysis of data, the most common usage pattern is to run multiple statistical methods on the same set\nof data.  Some of these methods use others.  For example, to calculate the standard deviation of a dataset, we first need the\nmean.\n\nAdditionally, some methods can be calculated quickly as data is inserted, thereby reducing the number of loops required to\nrun through the data during processing.\n\nFast stats maintains a running cache of several summary values as data is inserted making final calculation very fast.  It\ntrades off a small amount of additional memory usage for a large reduction in execution time.\n\ndownsides\n---------\n\nThe downside of how fast stats operates is that if your datapoints are too large, it may result in numeric overflow causing\nincorrect results.  Fast stats does not attempt to detect or correct for this.\n\nsynopsis\n--------\n\n```javascript\nvar Stats = require('fast-stats').Stats;\n\nvar s = new Stats().push(1, 2, 3, 10, 8, 4, 3);\nconsole.log(s.amean().toFixed(2));\n// 4.43\n```\n\ninstallation\n------------\n\n    $ npm install fast-stats\n\nAPI\n---\n\nfast-stats is completely synchronous.  There are no blocking methods and consequently no callbacks involved.  All\nruntime calls are executed in-memory and are fast.\n\n### Configuring the Stats object\n\nThe `Stats` constructor takes in a configuration object as a parameter.  This is a simple key-value list that tells\n`fast-stats` how to behave under certain conditions.\n\n```javascript\nvar s = new Stats({ bucket_precision: 10 });\n```\n\nThe following configuration options are recognised.  All of them are optional.\n\n *  `bucket_precision`: *[number]* Tells `fast-stats` to maintain a histogram of your dataset using this parameter as the least\n    count, or precision.\n\n    This is useful if you have a very large data set, and want to approximate percentile values like the median \n    without having to store the entire dataset in memory.  For example, if you had a million time measurements\n    between 0.5 and 1.5 seconds, you could store all million of them, or you could set up 1000 one millisecond\n    buckets and store a count of items in each bucket with a precision of 1 millisecond each.  If you reduce (higher\n    values are considered less precise) the precision to 10 milliseconds, the number of buckets reduces from 1000\n    to 100, taking up less memory overall.\n\n    By default, `fast-stats` will not maintain buckets since it does not know the least count and range of your\n    dataset in advance.\n\n    This option is required if you need to use the `distribution()` method.\n\n *  `buckets`: *[array of numbers]* Tells `fast-stats` to maintain a histogram of your dataset using these custom buckets.\n\n    Each number in the array is the upper limit of a bucket.  The lower limit of the first bucket is 0, the lower limit\n    for all other buckets is the upper limit of the previous bucket.\n\n    If you use both `bucket_precision` and `buckets`, `buckets` takes precedence.\n\n *  `store_data`: *[boolean]* Tells `fast-stats` not to store actual data values. This is useful to reduce memory utilisation\n    for large datasets, however it comes with a few caveats.\n\n    1.  You can no longer get an exact median or other percentile value out of your dataset, however you could\n        use bucketing (see `bucket_precision` above) to get an approximate percentile value.\n    2.  You can no longer run an exact `iqr` filter or a `band_pass` filter on the data, however you could use\n        bucketing to get an approximate filtered object.\n    3.  You can no longer get at the entire dataset or remove data from the dataset.\n\n    The mean, standard deviation and margin of error calculations are unaffected by this parameter.  If you use\n    bucketing, and only care about the mean, standard deviation and margin of error or an approximate median or\n    percentile value, set this option to false.\n\n    By default, `store_data` is `true`.\n\n\n### Getting data in and out\n\n#### Initialising and adding data\n\nThe `Stats` object looks a lot like an array in the way you add and remove data to its ends, however there is\nno direct access to individual elements.  Data is added to the object using the `push()` and `unshift()` methods.\nAll values must be numbers and behaviour is undefined if they are not.\n\nThe `push()` method takes in a list of values that will be added to the end of the current list and\nthe `unshift()` method takes in a list of values that will be added to the beginning of the list.\n\nInstead of passing in multiple parameters, you can also pass in an array of numbers as the first parameter.\n\nThe following are equivalent.\n\n```javascript\nvar s1, s2, s3, s4;\ns1 = new Stats().push(1, 2, 3, 10, 8, 4, 3);\n\ns2 = new Stats().push([1, 2, 3, 10, 8, 4, 3]);\n\ns3 = new Stats();\ns3.push(1, 2, 3, 10, 8, 4, 3);\n\ns4 = new Stats();\ns4.unshift(1, 2, 3, 10, 8, 4);\ns4.push(3);\n\nassert.equal(s1.amean().toFixed(2), s2.amean().toFixed(2));\nassert.equal(s1.amean().toFixed(2), s3.amean().toFixed(2));\nassert.equal(s1.amean().toFixed(2), s4.amean().toFixed(2));\n```\n\nNote that we use the `toFixed()` method of the Number class when comparing numbers.  Remember that even if you\npass in integers, values like the arithmetic mean, standard deviation and median can sometimes be floating point\nnumbers, and two floating point numbers may not necessarily be equal to the last decimal point.  The `toFixed()`\nmethod is useful to restrict how precise we want our comparison to be.  Be aware that it returns a string though.\n\n`fast-stats` does not use the `toFixed()` method internally.\n\nThe `push()` and `unshift()` methods return the `this` object.\n\n#### Removing data\n\nIf you need to remove data from a `Stats` object, use the `pop()` and `shift()` methods.  Their semantics are the\nsame as the `pop()` and `shift()` methods of Arrays.\n\n```javascript\nvar a = s1.pop();\nassert.equal(a, 3);\n\nvar b = s2.shift();\nassert.equal(b, 1);\n\nassert.equal(s1.length, 6);\nassert.equal(s2.length, 6);\nassert.ok(s1.amean() < s2.amean());\n```\n\n#### Clearing all data\n\nThe `reset()` method clears out all data.\n\n```javascript\ns4.reset();\nassert.equal(s4.length, 0);\n```\n\nThe `reset()` method returns a reference to the object, so you can chain methods.\n\n#### Making a copy\n\nThe `copy()` method returns a copy of the current Stats object.\n\n```javascript\ns4 = s3.copy();\n\nassert.equal(s3.length, s4.length);\n```\n\nAdditionally, the `copy()` method can create a new `Stats` object with a different configuration.\nThis is most useful if you need to change bucket sizes or precision.  Simply pass the new config\nobject as a parameter to the `copy()` method:\n\n```javascript\ns4 = s3.copy({store_data: false, bucket_precision: 10 });\n\n### Summaries & Averages\n\nThe term _Average_ is overloaded in Statistics.  It relates to a summary of a data set, but says nothing about how\nwe arrived at that summary.  There are many ways to summarise data, including the arithmetic mean, geometric mean,\nharmonic mean, median, mode and more.  `fast-stats` implements the Arithmetic Mean, the Geometric Mean and the Median.\nIt also implements a percentile method to get at any percentile of the data.\n\n#### Arithmetic Mean\n\nThe arithmetic mean is calculated as the sum of all data points divided by the number of data points.  This is useful\nfor data sets that are fairly uniform, following a linear or binomial distribution.  Use the `amean()` method or the `μ()`\nmethod to get at it:\n\n```javascript\nvar a = s1.amean();\nassert.equal(a.toFixed(2), \"4.67\");   // remember we popped out the last item of `s1` above.\n```\n\n#### Geometric Mean\n\nThe arithmetic mean is the `n`th root of the product of all data points where n is the number of data points. This is useful\nfor data sets that follow an exponential or log-normal distribution.  Use the `gmean()` method to get at it:\n\n```javascript\nvar a = s1.gmean();\nassert.equal(a.toFixed(2), \"3.53\");\n```\n\n#### Median\n\nThe median is the middle point of the dataset when sorted in ascending order.  This is useful if your dataset has a lot of\noutliers and noise that would not normally be found in a complete population.  Use the `median()` method to get at it:\n\n```javascript\nvar a = s1.median();\nassert.equal(a.toFixed(2), \"3.50\");\n```\n\nIf your data set contains an odd number of points, the median will be the middle point.  If it contains an even number of\npoints, then the median will be the arithmetic mean of the two middle points.\n\nIf your Stats object is configured to use buckets and has `store_data` set to false, then the median will be an approximation\nof the actual median.\n\n#### Any Percentile\n\nYou can also get at any percentile value within the data.  Use the `percentile()` method to get at this data.  The\n`percentile()` method takes in a single argument.  This is a number between 0 and 100 (both inclusive) that specifies\nwhich percentile point you want.\n\n```javascript\nvar p95 = s1.percentile(95);\nvar m = s1.percentile(50);\nvar q1 = s1.percentile(25);\n\nassert.equal(p95.toFixed(2), \"10.00\");\nassert.equal(m.toFixed(2), \"3.50\");\nassert.equal(q1.toFixed(2), \"2.50\");\n```\n\nPassing in 50 as an argument will return the median, while 25 and 75 will return the first and third quartiles respectively.\nThese three special values may be arithmetic means of two other values within the set.  All other arguments will return a\nnumber from the data set.\n\nIf your Stats object is configured to use buckets and has `store_data` set to false, then the percentile value returned will\nbe an approximation of the actual percentile based on the configured `bucket_precision` or `buckets`.\n\n#### Range\n\nThe `range()` method tells you the minimum and maximum values of your data set.  It returns an array of two values.  The\nfirst is the lower bound and the second is the upper bound.\n\n```javascript\nvar r = s1.range();\n\nassert.equal(r.length, 2);\nassert.equal(r[0], 1);\nassert.equal(r[1], 10);\n```\n#### Distribution\n\nThe `distribution()` method tells you how your data is distributed.  You need to set the `bucket_precision` or `buckets`\nconfiguration options if you plan on using this method.  It will then split your data into buckets based on the value of\n`bucket_precision` or `buckets` and tell you how many data points fall into each bucket.  You can use this to plot a \nhistogram of your data, or to compare it to commonly known distribution functions.\n\nThe return value is a sparse array of buckets with counts of datapoints per bucket.   To save on memory, any empty buckets\nare undefined.  You should treat an undefined bucket as if it had 0 datapoints.\n\nA bucket structure looks like this:\n```javascript\n{\n   bucket: <bucket midpoint>,\n   range:  [<bucket low>, <bucket high>],\n   count:  <number of datapoints>\n}\n```\n\nNote that the upper bound of the `range` is open, ie, the range does not include the upper bound.\n\n```javascript\nvar s7 = new Stats({bucket_precision: 10});\n\n// Populate s7 with sequence of squares from 0-10\n// 0 1 4 9 16 25 36 49 64 81 100\nfor(var i=0; i<=10; i++)\n\ts7.push(i*i);\n\n// distribution should be [4, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1]\n// but 0s are undefined to save on memory\nvar d=s7.distribution();\n\n// length should be one more than (max-min)/bucket_precision\nassert.equal(d.length, 11);\n\nd.forEach(function(e) {\n\tswitch(e.bucket) {\n\t\tcase 5: assert.equal(e.count, 4);\t// 0 1 4 9\n\t\t\tbreak;\n\t\tcase 15: assert.equal(e.count, 1);\t// 16\n\t\t\tbreak;\n\t\tcase 25: assert.equal(e.count, 1);\t// 25\n\t\t\tbreak;\n\t\tcase 35: assert.equal(e.count, 1);\t// 36\n\t\t\tbreak;\n\t\tcase 45: assert.equal(e.count, 1);\t// 49\n\t\t\tbreak;\n\t\tcase 55: assert.equal(e.count, 0);\n\t\t\tbreak;\n\t\tcase 65: assert.equal(e.count, 1);\t// 64\n\t\t\tbreak;\n\t\tcase 75: assert.equal(e.count, 0);\n\t\t\tbreak;\n\t\tcase 85: assert.equal(e.count, 1);\t// 81\n\t\t\tbreak;\n\t\tcase 95: assert.equal(e.count, 0);\n\t\t\tbreak;\n\t\tcase 105: assert.equal(e.count, 1);\t// 100\n\t\t\tbreak;\n\t\tdefault: assert.fail(e.bucket, \"\", \"\", \"Unexpected bucket\");\n\t}\n});\n```\n\nUsing custom buckets instead:\n\n```javascript\nvar assert = require('assert'),\n    Stats = require('fast-stats').Stats;\n\nvar s1 = new Stats({buckets: [1, 2, 3, 5, 8, 13]});\nfor(var i=0; i<20; i++)\n\ts1.push(i);\n\nvar d = s1.distribution();\n\nd.forEach(function(e) {\n\tswitch(e.bucket) {\n\t\tcase 0.5: assert.equal(e.count, 1);\t// 0\n\t\t\tbreak;\n\t\tcase 1.5: assert.equal(e.count, 1);\t// 1\n\t\t\tbreak;\n\t\tcase 2.5: assert.equal(e.count, 1);\t// 2\n\t\t\tbreak;\n\t\tcase 4: assert.equal(e.count, 2);\t// 3, 4\n\t\t\tbreak;\n\t\tcase 6.5: assert.equal(e.count, 3);\t// 5, 6, 7\n\t\t\tbreak;\n\t\tcase 10.5: assert.equal(e.count, 5);\t// 8, 9, 10, 11, 12\n\t\t\tbreak;\n\t\tcase 16: assert.equal(e.count, 7);\t// 13, 14, 15, 16, 17, 18, 19\n\t\t\tbreak;\n\t\tdefault: assert.fail(e.bucket, \"\", \"\", \"Unexpected bucket\");\n\t}\n});\n```\n\n### Data Accuracy\n\nThere are various statistical values that tell you how accurate or uniform your data is.  `fast-stats` implements\nthe Arithmetic Standard Deviation, Geometric Standard Deviation and 95% Confidence Interval Margin of Error.\n\n#### Arithmetic Standard Deviation\n\nAlso commonly just called the Standard Deviation, with the symbol σ.  This tells you the spread of your data if\nit follows a normal (or close to normal) distribution, ie, the bell curve.  `fast-stats` is really fast at\ncalculating the standard deviation of a dataset.  Use the `stddev()` method or the `σ()` method to get at it.\n\n```javascript\nvar sd = s1.σ();\n\nassert.equal(sd.toFixed(2), '3.25');\n```\n\nThe arithmetic standard deviation is used in conjunction with the arithmetic mean to tell you the spread of your\ndataset: `[amean-stddev, amean+stddev]`.  Note that you could also use 2 or 3 standard deviations for different\nspreads.\n\n#### Geometric Standard Deviation\n\nThe geometric mean tells you the spread of your data if it follows a log-normal or exponential distribution.\nUse the `gstddev()` method to get at it.\n\n```javascript\nvar gsd = s1.gstddev();\n\nassert.equal(gsd.toFixed(2), '2.20');\n```\n\nThe geometric standard deviation is used in conjunction with the geometric mean to tell you the spread of your\ndataset: `[gmean/gstddev, gmean*gstddev]`.  Note that this range is not symmetric around the geometric mean.\n\n#### 95% Confidence Margin of Error\n\nThe Margin of Error value tells you the range within which the real arithmetic mean of the population is likely to\nbe with 95% confidence.  Use the `moe()` method to get at it.\n\n```javascript\nvar moe = s1.moe();\n\nassert.equal(moe.toFixed(2), '2.60');\n```\n\nThis value suggests that we are 95% certain that the real mean of the population is within 2.60 of the calculated \narithmetic mean of 4.67.  We could use this to find out the percent error in our sample.  In this case there is a\n55.71% error.\n\nThe margin of error is inversely proportional to the square root of the number of data points, so increasing the\nsize of your sample will reduce the margin of error.  It is good to strive for a margin of error of less than 5%.\n\n### Data filtering\n\nWhen dealing with statistical samples, it may be necessary to filter the dataset to get rid of outliers.  Sometimes\nan outlier is fairly obvious, and you can specify an upper and lower limit for it.   At other times, outliers are\nonly apparent when looking at the rest of the dataset.  Inter-Quartile-Range filtering is useful to filter out these\nkinds of data sets.\n\nNote that if your Stats object is configured to use buckets and has `store_data` set to false, then all filtering\nwill be done on an approximation of the data based on the configured value of `bucket_precision`.  For example,\nif you have a set of numbers from 1-100 with `bucket_precision` set to 1, then filtering the dataset between 55\nand 85 will get you a dataset between 55 and 85.  If instead, `bucket_precision` is set to 10, then the filtered\ndataset will approximately range from 50 to 90.  Note, however, that the `range()` method will attempt to match as\nclosely as possible the real range.\n\n#### Band-pass filtering\n\nThe `band_pass()` filter method returns a new `Stats` object with all its data points within the specified range.\nThis method takes in three arguments.  The first is the lower bound of the range, the second is the upper bound\nof the range.  Both these arguments are required.\n\nThe third argument specifies whether the range is open or closed.  An open range does not include the upper and\nlower bounds while a closed range includes them.  If not specified (or set to `false`), the range is closed.  If\nset to `true` the range is open.\n\n```javascript\nvar s5 = s1.band_pass(3, 8);\nvar r = s5.range();\n\nassert.equal(r[0], 3);\nassert.equal(r[1], 8);\n\ns5 = s1.band_pass(3, 8, true);\nr = s5.range();\n\nassert.equal(r[0], 4);\nassert.equal(r[1], 4);\n```\n\nBand pass filtering should be used if the range for your data is rigid and never changes.\n\n#### IQR Filtering\n\nIQR, or Inter Quartile Range filtering filters data based on the spread of the data.  It is much more adaptive to\nchanges in data ranges.  Use the `iqr()` method to IQR filter a dataset.  The `iqr()` method does not accept\nany arguments.\n\n\n```javascript\nvar s6 = s1.iqr();\nr = s6.range();\n\nassert.equal(r[0], 1);\nassert.equal(r[1], 10);\n```\n\nIn some cases, IQR filtering may not filter out anything.  This can happen if the acceptable range is wider than\nthe bounds of your dataset.\n\n\nReferences\n----------\n\nWikipedia is a great place to get information about Statistical functions.\n\nCopyright\n---------\n\n`fast-stats` is Copyright 2011 Philip Tellis <philip@bluesmoon.info> and the latest version of the code is\navailable at https://github.com/bluesmoon/node-faststats\n\nLicense\n-------\n\nApache 2.0.  See the [LICENSE](https://github.com/bluesmoon/node-faststats/blob/master/LICENSE) file for details.\n",
  "_id": "fast-stats@0.0.2",
  "dist": {
    "shasum": "61c75de0d94f96f427659752d6541f1a6af9a0c1",
    "tarball": "http://registry.npmjs.org/fast-stats/-/fast-stats-0.0.2.tgz"
  },
  "_npmVersion": "1.1.59",
  "_npmUser": {
    "name": "bluesmoon",
    "email": "philip@bluesmoon.info"
  },
  "maintainers": [
    {
      "name": "bluesmoon",
      "email": "philip@bluesmoon.info"
    }
  ],
  "directories": {},
  "_shasum": "61c75de0d94f96f427659752d6541f1a6af9a0c1",
  "_from": "fast-stats@0.0.2",
  "_resolved": "https://registry.npmjs.org/fast-stats/-/fast-stats-0.0.2.tgz",
  "bugs": {
    "url": "https://github.com/bluesmoon/node-faststats/issues"
  }
}
