spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[SLOPE] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-06-23 02:41:44
stats
8 file(s) changed, 114 insertions(+), 5 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Statistical.js
src/Formulas/AllFormulas.ts
src/Formulas/Statistical.ts
tests/Formulas/StatisticalTest.ts
tests/SheetFormulaTest.ts
  1diff --git a/DOCS.md b/DOCS.md
  2index 6dced99..8199e0d 100644
  3--- a/DOCS.md
  4+++ b/DOCS.md
  5@@ -1507,6 +1507,15 @@
  6 @returns {number} 
  7 @constructor
  8 ```
  9+
 10+### SLOPE 
 11+
 12+```
 13+  Returns the slope of the line calculated from linear regression of a range. Any text values passed in will be ignored 
 14+@param rangeY - The range or array representing the dependent data. 
 15+@param rangeX - The range or array representing the independent data. 
 16+@constructor
 17+```
 18 ## Text
 19 
 20 
 21diff --git a/TODO.md b/TODO.md
 22index 80e1b53..57f5868 100644
 23--- a/TODO.md
 24+++ b/TODO.md
 25@@ -90,7 +90,6 @@ For example 64 tbs to a qt.
 26 * RANK.EQ
 27 * RSQ
 28 * SKEW
 29-* SLOPE
 30 * SMALL
 31 * STANDARDIZE
 32 * STEYX
 33diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
 34index aeabfdb..60e0a5c 100644
 35--- a/dist/Formulas/AllFormulas.js
 36+++ b/dist/Formulas/AllFormulas.js
 37@@ -136,6 +136,7 @@ exports.STDEVA = Statistical_1.STDEVA;
 38 exports.STDEVP = Statistical_1.STDEVP;
 39 exports.STDEVPA = Statistical_1.STDEVPA;
 40 exports.TRIMMEAN = Statistical_1.TRIMMEAN;
 41+exports.SLOPE = Statistical_1.SLOPE;
 42 var Text_1 = require("./Text");
 43 exports.ARABIC = Text_1.ARABIC;
 44 exports.CHAR = Text_1.CHAR;
 45diff --git a/dist/Formulas/Statistical.js b/dist/Formulas/Statistical.js
 46index d8e123a..8cd1552 100644
 47--- a/dist/Formulas/Statistical.js
 48+++ b/dist/Formulas/Statistical.js
 49@@ -723,3 +723,39 @@ var TRIMMEAN = function (range, percent) {
 50     return MathHelpers_1.mean(tmp.slice(0, tmp.length - trim));
 51 };
 52 exports.TRIMMEAN = TRIMMEAN;
 53+/**
 54+ * Returns the slope of the line calculated from linear regression of a range. Any text values passed in will be ignored
 55+ * @param rangeY - The range or array representing the dependent data.
 56+ * @param rangeX - The range or array representing the independent data.
 57+ * @constructor
 58+ */
 59+var SLOPE = function (rangeY, rangeX) {
 60+    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "SLOPE");
 61+    var dataX = Filter_1.Filter.flattenAndThrow(rangeX).filter(function (value) {
 62+        return typeof value !== "string";
 63+    }).map(function (value) {
 64+        return TypeConverter_1.TypeConverter.valueToNumber(value);
 65+    });
 66+    var dataY = Filter_1.Filter.flattenAndThrow(rangeY).filter(function (value) {
 67+        return typeof value !== "string";
 68+    }).map(function (value) {
 69+        return TypeConverter_1.TypeConverter.valueToNumber(value);
 70+    });
 71+    if (dataX.length !== dataY.length) {
 72+        throw new Errors_1.NAError("SLOPE has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
 73+    }
 74+    var xmean = MathHelpers_1.mean(dataX);
 75+    var ymean = MathHelpers_1.mean(dataY);
 76+    var n = dataX.length;
 77+    var num = 0;
 78+    var den = 0;
 79+    for (var i = 0; i < n; i++) {
 80+        num += (dataX[i] - xmean) * (dataY[i] - ymean);
 81+        den += Math.pow(dataX[i] - xmean, 2);
 82+    }
 83+    if (den === 0) {
 84+        throw new Errors_1.DivZeroError("Evaluation of function SLOPE caused a divide by zero error.");
 85+    }
 86+    return num / den;
 87+};
 88+exports.SLOPE = SLOPE;
 89diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
 90index 70c9a0d..a3d63ca 100644
 91--- a/src/Formulas/AllFormulas.ts
 92+++ b/src/Formulas/AllFormulas.ts
 93@@ -141,7 +141,8 @@ import {
 94   STDEVA,
 95   STDEVP,
 96   STDEVPA,
 97-  TRIMMEAN
 98+  TRIMMEAN,
 99+  SLOPE
100 } from "./Statistical";
101 import {
102   ARABIC,
103@@ -347,5 +348,6 @@ export {
104   FACTDOUBLE,
105   FREQUENCY,
106   GROWTH,
107-  TRIMMEAN
108+  TRIMMEAN,
109+  SLOPE
110 }
111\ No newline at end of file
112diff --git a/src/Formulas/Statistical.ts b/src/Formulas/Statistical.ts
113index b6bbe82..c400066 100644
114--- a/src/Formulas/Statistical.ts
115+++ b/src/Formulas/Statistical.ts
116@@ -703,6 +703,43 @@ var TRIMMEAN = function (range, percent) {
117 };
118 
119 
120+/**
121+ * Returns the slope of the line calculated from linear regression of a range. Any text values passed in will be ignored
122+ * @param rangeY - The range or array representing the dependent data.
123+ * @param rangeX - The range or array representing the independent data.
124+ * @constructor
125+ */
126+var SLOPE = function (rangeY, rangeX) {
127+  ArgsChecker.checkLength(arguments, 2, "SLOPE");
128+  var dataX = Filter.flattenAndThrow(rangeX).filter(function (value) {
129+    return typeof value !== "string";
130+  }).map(function (value) {
131+    return TypeConverter.valueToNumber(value);
132+  });
133+  var dataY = Filter.flattenAndThrow(rangeY).filter(function (value) {
134+    return typeof value !== "string";
135+  }).map(function (value) {
136+    return TypeConverter.valueToNumber(value);
137+  });
138+  if (dataX.length !== dataY.length) {
139+    throw new NAError("SLOPE has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
140+  }
141+  var xmean = mean(dataX);
142+  var ymean = mean(dataY);
143+  var n = dataX.length;
144+  var num = 0;
145+  var den = 0;
146+  for (var i = 0; i < n; i++) {
147+    num += (dataX[i] - xmean) * (dataY[i] - ymean);
148+    den += Math.pow(dataX[i] - xmean, 2);
149+  }
150+  if (den === 0) {
151+    throw new DivZeroError("Evaluation of function SLOPE caused a divide by zero error.");
152+  }
153+  return num / den;
154+};
155+
156+
157 export {
158   AVERAGE,
159   AVERAGEA,
160@@ -729,5 +766,6 @@ export {
161   STDEVA,
162   STDEVP,
163   STDEVPA,
164-  TRIMMEAN
165+  TRIMMEAN,
166+  SLOPE
167 }
168\ No newline at end of file
169diff --git a/tests/Formulas/StatisticalTest.ts b/tests/Formulas/StatisticalTest.ts
170index 65c5aaa..cebdb11 100644
171--- a/tests/Formulas/StatisticalTest.ts
172+++ b/tests/Formulas/StatisticalTest.ts
173@@ -24,7 +24,8 @@ import {
174   STDEVA,
175   STDEVP,
176   STDEVPA,
177-  TRIMMEAN
178+  TRIMMEAN,
179+  SLOPE
180 } from "../../src/Formulas/Statistical";
181 import * as ERRORS from "../../src/Errors";
182 import {
183@@ -568,4 +569,21 @@ test("TRIMMEAN", function() {
184   catchAndAssertEquals(function() {
185     TRIMMEAN([10], -1);
186   }, ERRORS.NUM_ERROR);
187+});
188+
189+test("SLOPE", function() {
190+  assertEquals(SLOPE([1, 2.2, 4, 5.5, 6, 8], [1.9, 22.2, 44, 55.5, 88, 99.1]), 0.06727907586278936);
191+  assertEquals(SLOPE([1.1, 2.44, 5, 10.5, 600, 800], [1.9, 22.2, 44, 55.5, 88, 99.1]), 8.50783378332324);
192+  assertEquals(SLOPE([1.1, 2.44, 5, 10.5, 600, "ignore", 800], [1.9, 22.2, 44, 55.5, 88, 99.1]), 8.50783378332324);
193+  assertEquals(SLOPE([600, 800], [44, 4.1]), -5.012531328320802);
194+  assertEquals(SLOPE([1, 2.2, 4, 5.5, 6, 8, true], [1.9, 22.2, 44, 55.5, 88,  99.1, true]), 0.06743685772979165);
195+  catchAndAssertEquals(function() {
196+    SLOPE([1], [0]);
197+  }, ERRORS.DIV_ZERO_ERROR);
198+  catchAndAssertEquals(function() {
199+    SLOPE([1], [1]);
200+  }, ERRORS.DIV_ZERO_ERROR);
201+  catchAndAssertEquals(function() {
202+    SLOPE([1, 3], [1]);
203+  }, ERRORS.NA_ERROR);
204 });
205\ No newline at end of file
206diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
207index 312d32e..def495a 100644
208--- a/tests/SheetFormulaTest.ts
209+++ b/tests/SheetFormulaTest.ts
210@@ -691,6 +691,10 @@ test("Sheet TRIMMEAN", function(){
211   assertFormulaEquals('=TRIMMEAN([1], 0.1)', 1);
212 });
213 
214+test("Sheet SLOPE", function(){
215+  assertFormulaEquals('=SLOPE([600, 800], [44, 4.1])', -5.012531328320802);
216+});
217+
218 test("Sheet *", function(){
219   assertFormulaEquals('= 10 * 10', 100);
220   assertFormulaEquals('= 10 * 0', 0);