1 | var chiSquared = require('chi-squared');
|
2 | var decimalAdjust = require('decimal-adjust');
|
3 |
|
4 | var z = 1.959964;
|
5 |
|
6 | (function(){
|
7 | if (!Math.round10) {
|
8 | Math.round10 = function(value, exp) {
|
9 | return decimalAdjust('round', value, exp);
|
10 | };
|
11 | }
|
12 |
|
13 | if (!Math.floor10) {
|
14 | Math.floor10 = function(value, exp) {
|
15 | return decimalAdjust('floor', value, exp);
|
16 | };
|
17 | }
|
18 |
|
19 | if (!Math.ceil10) {
|
20 | Math.ceil10 = function(value, exp) {
|
21 | return decimalAdjust('ceil', value, exp);
|
22 | };
|
23 | }
|
24 | })();
|
25 |
|
26 | function getDiagnosticTest(testValues) {
|
27 | var nr1, nc1,
|
28 | nr2, nc2;
|
29 |
|
30 | var bigN;
|
31 |
|
32 | var sensitivity, sensitivityConfidence;
|
33 | var specificity, specificityConfidence;
|
34 | var ppv, ppvConfidence;
|
35 | var npv, npvConfidence;
|
36 | var lrPlusLowerLimit, lrPlusUpperLimit;
|
37 | var lrMinusLowerLimit, lrMinusUpperLimit;
|
38 |
|
39 | var a = testValues.testPositiveDisease;
|
40 | var b = testValues.testPositiveNoDisease;
|
41 | var c = testValues.testNegativeDisease;
|
42 | var d = testValues.testNegativeNoDisease;
|
43 |
|
44 | var lrPlus = testValues.lrPlus;
|
45 | var lrNegative = testValues.lrMinus;
|
46 |
|
47 | nr1 = a + b;
|
48 | nc1 = a + c;
|
49 | nc2 = b + d;
|
50 | nr2 = c + d;
|
51 |
|
52 | bigN = a + b + c + d;
|
53 |
|
54 | if (nc1 === 0 || nc2 === 0 || nr1 === 0 || nr2 === 0) {
|
55 | return false;
|
56 | }
|
57 |
|
58 | sensitivity = a / nc1;
|
59 | sensitivityConfidence = _getDiagnosticTestConfidence(a, c, nc1);
|
60 |
|
61 | if (typeof sensitivity !== 'number' || isNaN(sensitivity) || typeof sensitivityConfidence !== "object" || sensitivityConfidence === null) {
|
62 | return false;
|
63 | }
|
64 |
|
65 | specificity = d / nc2;
|
66 | specificityConfidence = _getDiagnosticTestConfidence(d, b, nc2);
|
67 |
|
68 | if (typeof specificity !== 'number' || isNaN(specificity) || typeof specificityConfidence !== "object" || specificityConfidence === null) {
|
69 | return false;
|
70 | }
|
71 |
|
72 | ppv = a / nr1;
|
73 | ppvConfidence = _getDiagnosticTestConfidence(a, b, nr1);
|
74 |
|
75 | if (typeof ppv !== 'number' || isNaN(ppv) || typeof ppvConfidence !== "object" || ppvConfidence === null) {
|
76 | return false;
|
77 | }
|
78 |
|
79 | npv = d / nr2;
|
80 | npvConfidence = _getDiagnosticTestConfidence(d, c, nr2);
|
81 |
|
82 | if (typeof ppv !== 'number' || isNaN(ppv) || typeof ppvConfidence !== "object" || ppvConfidence === null) {
|
83 | return false;
|
84 | }
|
85 |
|
86 | if ((1 - specificity) === 0 || specificity === 0 || nc1 * b === 0 || a * nc1 === 0 || b * nc2 === 0 || nc1 * d === 0 || c * nc1 === 0 || d * nc2 === 0) {
|
87 | return false;
|
88 | }
|
89 |
|
90 | lrPlus = sensitivity / (1 - specificity);
|
91 | lrPlusLowerLimit = Math.exp(Math.log((nc2 * a) / (nc1 * b)) - (z * Math.sqrt((c / (a * nc1)) + (d / (b * nc2)))));
|
92 | lrPlusUpperLimit = Math.exp(Math.log((nc2 * a) / (nc1 * b)) + (z * Math.sqrt((c / (a * nc1)) + (d / (b * nc2)))));
|
93 |
|
94 | if (typeof lrPlus !== 'number' || isNaN(lrPlus)) {
|
95 | return false;
|
96 | }
|
97 |
|
98 | if (typeof lrPlusLowerLimit !== 'number' || isNaN(lrPlusLowerLimit)) {
|
99 | return false;
|
100 | }
|
101 |
|
102 | if (typeof lrPlusUpperLimit !== 'number' || isNaN(lrPlusUpperLimit)) {
|
103 | return false;
|
104 | }
|
105 |
|
106 | lrMinus = (1 - sensitivity) / specificity;
|
107 | lrMinusLowerLimit = Math.exp(Math.log((nc2 * c) / (nc1 * d)) - (z * Math.sqrt((a / (c * nc1)) + (b / (d * nc2)))));
|
108 | lrMinusUpperLimit = Math.exp(Math.log((nc2 * c) / (nc1 * d)) + (z * Math.sqrt((a / (c * nc1)) + (b / (d * nc2)))));
|
109 |
|
110 | if (typeof lrMinus !== 'number' || isNaN(lrMinus)) {
|
111 | return false;
|
112 | }
|
113 |
|
114 | if (typeof lrMinusLowerLimit !== 'number' || isNaN(lrMinusLowerLimit)) {
|
115 | return false;
|
116 | }
|
117 |
|
118 | if (typeof lrMinusUpperLimit !== 'number' || isNaN(lrMinusUpperLimit)) {
|
119 | return false;
|
120 | }
|
121 |
|
122 | return {
|
123 | 'graph': true,
|
124 | 'sensitivity': Math.round10(sensitivity, -3),
|
125 | 'sensitivityLowerLimit': Math.round10(sensitivityConfidence['lower'], -3),
|
126 | 'sensitivityUpperLimit': Math.round10(sensitivityConfidence['upper'], -3),
|
127 | 'specificity': Math.round10(specificity, -3),
|
128 | 'specificityLowerLimit': Math.round10(specificityConfidence['lower'], -3),
|
129 | 'specificityUpperLimit': Math.round10(specificityConfidence['upper'], -3),
|
130 | 'ppv': Math.round10(ppv, -3),
|
131 | 'ppvLowerLimit': Math.round10(ppvConfidence['lower'], -3),
|
132 | 'ppvUpperLimit': Math.round10(ppvConfidence['upper'], -3),
|
133 | 'npv': Math.round10(npv, -3),
|
134 | 'npvLowerLimit': Math.round10(npvConfidence['lower'], -3),
|
135 | 'npvUpperLimit': Math.round10(npvConfidence['upper'], -3),
|
136 | 'lrPlus': Math.round10(lrPlus, -3),
|
137 | 'lrPlusLowerLimit': Math.round10(lrPlusLowerLimit, -3),
|
138 | 'lrPlusUpperLimit': Math.round10(lrPlusUpperLimit, -3),
|
139 | 'lrMinus': Math.round10(lrMinus, -3),
|
140 | 'lrMinusLowerLimit': Math.round10(lrMinusLowerLimit, -3),
|
141 | 'lrMinusUpperLimit': Math.round10(lrMinusUpperLimit, -3)
|
142 | };
|
143 | }
|
144 |
|
145 | function getProspectiveStudy(testValues) {
|
146 | var a = testValues.treatedDisease;
|
147 | var b = testValues.treatedNoDisease;
|
148 | var c = testValues.notTreatedDisease;
|
149 | var d = testValues.notTreatedNoDisease;
|
150 |
|
151 | var chiSquared = _getChiSquared(a, b, c, d);
|
152 |
|
153 | var pValue;
|
154 | var rr, rrNumerator, rrDenominator, rrrLowerLimit, rrrUpperLimit;
|
155 |
|
156 | var arr, arrConfidence;
|
157 | var nnt, nntConfidence;
|
158 |
|
159 | if (typeof chiSquared !== 'number' || isNaN(chiSquared)) {
|
160 | return false;
|
161 | }
|
162 |
|
163 | pValue = _getPValue(chiSquared);
|
164 |
|
165 | if (typeof pValue !== 'number' || isNaN(pValue)) {
|
166 | return false;
|
167 | }
|
168 |
|
169 | rrNumerator = a * (c + d);
|
170 | rrDenominator = c * (a + b);
|
171 |
|
172 | if (typeof rrDenominator !== 'number' || isNaN(rrDenominator)) {
|
173 | return false;
|
174 | }
|
175 |
|
176 | rr = rrNumerator / rrDenominator;
|
177 |
|
178 | if (typeof rr !== 'number' || isNaN(rr)) {
|
179 | return false;
|
180 | }
|
181 |
|
182 | if (c === 0 || (c + d) === 0 || a === 0 || a + b === 0) {
|
183 | return false
|
184 | }
|
185 |
|
186 | rrLowerLimit = Math.exp(Math.log(rr) - (z * Math.sqrt((1 / c) - (1 / (c + d)) + (1 / a) - (1 / (a + b)))));
|
187 | rrUpperLimit = Math.exp(Math.log(rr) + (z * Math.sqrt((1 / c) - (1 / (c + d)) + (1 / a) - (1 / (a + b)))));
|
188 |
|
189 | if (typeof rrLowerLimit !== 'number' || isNaN(rrLowerLimit)) {
|
190 | return false;
|
191 | }
|
192 | if (typeof rrUpperLimit !== 'number' || isNaN(rrUpperLimit)) {
|
193 | return false;
|
194 | }
|
195 |
|
196 | arr = _getArr(a, b, c, d);
|
197 | arrConfidence = _getArrConfidence(arr, a, b, c, d);
|
198 |
|
199 | if (typeof arr !== 'number' || isNaN(arr)) {
|
200 | return false;
|
201 | }
|
202 |
|
203 | if (typeof arrConfidence !== 'object' || arrConfidence === null) {
|
204 | return false;
|
205 | }
|
206 |
|
207 | nnt = _getNnt(arr);
|
208 | nntConfidence = _getNntConfidence(arrConfidence);
|
209 |
|
210 | if (typeof nnt !== 'number' || isNaN(nnt)) {
|
211 | return false;
|
212 | }
|
213 |
|
214 | if (typeof nntConfidence !== 'object' || nntConfidence === null) {
|
215 | return false;
|
216 | }
|
217 |
|
218 | return {
|
219 | 'chiSquared': Math.round10(chiSquared, -3),
|
220 | 'pValue': Math.round10(pValue, -3),
|
221 | 'rr': Math.round10(rr, -3),
|
222 | 'rrLowerLimit': Math.round10(rrLowerLimit, -3),
|
223 | 'rrUpperLimit': Math.round10(rrUpperLimit, -3),
|
224 | 'arr': Math.round10(arr, -3),
|
225 | 'arrLowerLimit': Math.round10(arrConfidence['lower'], -3),
|
226 | 'arrUpperLimit': Math.round10(arrConfidence['upper'], -3),
|
227 | 'nnt': Math.round10(nnt, -3),
|
228 | 'nntLowerLimit': Math.round10(nntConfidence['lower'], -3),
|
229 | 'nntUpperLimit': Math.round10(nntConfidence['upper'], -3)
|
230 | };
|
231 | }
|
232 |
|
233 | function getCaseControlStudy(testValues) {
|
234 | var a = testValues.caseExposed;
|
235 | var b = testValues.caseNotExposed;
|
236 | var c = testValues.controlExposed;
|
237 | var d = testValues.controlNotExposed;
|
238 |
|
239 | var chiSquared = _getChiSquared(a, b, c, d);
|
240 |
|
241 | var pValue;
|
242 | var orNumerator, orDenominator, or;
|
243 | var orLowerLimit, orUpperLimit;
|
244 |
|
245 | if (typeof chiSquared !== 'number' || isNaN(chiSquared)) {
|
246 | return false;
|
247 | }
|
248 |
|
249 | pValue = _getPValue(chiSquared);
|
250 |
|
251 | if (typeof pValue !== 'number' || isNaN(pValue)) {
|
252 | return false;
|
253 | }
|
254 |
|
255 | orNumerator = a * d;
|
256 | orDenominator = b * c;
|
257 |
|
258 | if (orDenominator === 0) {
|
259 | return false;
|
260 | }
|
261 |
|
262 | or = orNumerator / orDenominator;
|
263 |
|
264 | if (typeof or !== 'number' || isNaN(or)) {
|
265 | return false;
|
266 | }
|
267 |
|
268 | if (a === 0 || b === 0 || c === 0 || d === 0) {
|
269 | return false;
|
270 | }
|
271 |
|
272 | orLowerLimit = Math.exp(Math.log(or) - (z * Math.sqrt((1 / a) + (1 / b) + (1 / c) + (1 / d))));
|
273 | orUpperLimit = Math.exp(Math.log(or) + (z * Math.sqrt((1 / a) + (1 / b) + (1 / c) + (1/d))));
|
274 |
|
275 | if (typeof orLowerLimit !== 'number' || isNaN(orLowerLimit)) {
|
276 | return false;
|
277 | }
|
278 |
|
279 | if (typeof orUpperLimit !== 'number' || isNaN(orUpperLimit)) {
|
280 | return false;
|
281 | }
|
282 |
|
283 | return {
|
284 | "chiSquared": Math.round10(chiSquared, -3),
|
285 | "pValue": Math.round10(pValue, -3),
|
286 | "or": Math.round10(or, -3),
|
287 | "orLowerLimit": Math.round10(orLowerLimit, -3),
|
288 | "orUpperLimit": Math.round10(orUpperLimit, -3)
|
289 | };
|
290 | }
|
291 |
|
292 | function getRct(testValues) {
|
293 | var a = testValues.experimentalOutcome;
|
294 | var b = testValues.experimentalNoOutcome;
|
295 | var c = testValues.controlOutcome;
|
296 | var d = testValues.controlNoOutcome;
|
297 |
|
298 | var chiSquared = _getChiSquared(a, b, c, d);
|
299 | var pValue;
|
300 | var rrr, rrrNumerator, rrrDenominator;
|
301 | var rrrLowerLimit, rrrUpperLimit;
|
302 | var arr, arrConfidence;
|
303 | var nnt, nntConfidence;
|
304 |
|
305 | if (typeof chiSquared !== 'number' || isNaN(chiSquared)) {
|
306 | return false;
|
307 | }
|
308 |
|
309 | pValue = _getPValue(chiSquared);
|
310 |
|
311 | if (typeof pValue !== 'number' || isNaN(pValue)) {
|
312 | return false;
|
313 | }
|
314 |
|
315 | if ((c + d) === 0 || (a + b) === 0) {
|
316 | return false;
|
317 | }
|
318 |
|
319 | rrrNumerator = (c / (c + d)) - (a / (a + b));
|
320 | rrrDenominator = c / (c + d);
|
321 |
|
322 | if (rrrDenominator === 0) {
|
323 | return false;
|
324 | }
|
325 |
|
326 | rrr = rrrNumerator / rrrDenominator;
|
327 |
|
328 | if (typeof rrr !== 'number' || isNaN(rrr)) {
|
329 | return false;
|
330 | }
|
331 |
|
332 | if ((c * (a + b)) === 0 || c === 0 || (c + d) === 0 || a === 0 || (a + b) === 0) {
|
333 | return false;
|
334 | }
|
335 |
|
336 | rrrLowerLimit = 1 - (Math.exp(Math.log((a * (c+d)) / (c * (a + b))) + z * Math.sqrt((1 / c) - (1 / (c + d)) + (1 / a) - (1 / (a + b)))));
|
337 | rrrUpperLimit = 1 - (Math.exp(Math.log((a * (c+d)) / (c * (a + b))) - z * Math.sqrt((1 / c) - (1 / (c + d)) + (1 / a) - (1 / (a + b)))));
|
338 |
|
339 | if (typeof rrrLowerLimit !== 'number' || isNaN(rrrLowerLimit)) {
|
340 | return false;
|
341 | }
|
342 |
|
343 | if (typeof rrrUpperLimit !== 'number' || isNaN(rrrUpperLimit)) {
|
344 | return false;
|
345 | }
|
346 |
|
347 | arr = _getArr(a, b, c, d);
|
348 | arrConfidence = _getArrConfidence(arr, a, b, c, d);
|
349 |
|
350 | if (typeof arr !== 'number' || isNaN(arr)) {
|
351 | return false;
|
352 | }
|
353 |
|
354 | if (typeof arrConfidence !== 'object' || arrConfidence === null) {
|
355 | return false;
|
356 | }
|
357 |
|
358 | nnt = _getNnt(arr);
|
359 | nntConfidence = _getNntConfidence(arrConfidence);
|
360 |
|
361 | if (typeof nnt !== 'number' || isNaN(nnt)) {
|
362 | return false;
|
363 | }
|
364 |
|
365 | if (typeof nntConfidence !== 'object' || nntConfidence === null) {
|
366 | return false;
|
367 | }
|
368 |
|
369 | return {
|
370 | "chiSquared": Math.round10(chiSquared, -3),
|
371 | "pValue": Math.round10(pValue, -3),
|
372 | "rrr": Math.round10(rrr, -3),
|
373 | "rrrLowerLimit": Math.round10(rrrLowerLimit, -3),
|
374 | "rrrUpperLimit": Math.round10(rrrUpperLimit, -3),
|
375 | "arr": Math.round10(arr, -3),
|
376 | "arrLowerLimit": Math.round10(arrConfidence['lower'], -3),
|
377 | "arrUpperLimit": Math.round10(arrConfidence['upper'], -3),
|
378 | "nnt": Math.round10(nnt, -3),
|
379 | "nntLowerLimit": Math.round10(nntConfidence['lower'], -3),
|
380 | "nntUpperLimit": Math.round10(nntConfidence['upper'], -3)
|
381 | };
|
382 | }
|
383 |
|
384 | function getCoordinatesOfCurve(lr, canvas) {
|
385 | var points = [];
|
386 |
|
387 | var pretestProb = 0;
|
388 |
|
389 |
|
390 |
|
391 | while (pretestProb <= 1) {
|
392 | pretestProb = pretestProb + 0.001;
|
393 |
|
394 | pretestOdds = 0;
|
395 | if (pretestProb != 1) {
|
396 | pretestOdds = pretestProb / (1 - pretestProb);
|
397 | }
|
398 |
|
399 | posttestProbNumerator = pretestOdds * lr;
|
400 | posttestProbDenominator = 1 + (pretestOdds * lr);
|
401 |
|
402 | posttestProb = 0;
|
403 | if (posttestProbDenominator != 0) {
|
404 | posttestProb = posttestProbNumerator / posttestProbDenominator;
|
405 | }
|
406 |
|
407 | x = pretestProb * canvas.width;
|
408 | y = canvas.height - posttestProb * canvas.height;
|
409 |
|
410 | var point = {
|
411 | "x": x,
|
412 | "y": y
|
413 | };
|
414 |
|
415 | points.push(point);
|
416 | }
|
417 | return points;
|
418 | }
|
419 |
|
420 | function _getDiagnosticTestConfidence(y, t, n) {
|
421 | var lowerNumerator, upperNumerator, denominator;
|
422 | var newUpper, newLower;
|
423 |
|
424 | if (typeof y !== 'number' || isNaN(y)) {
|
425 | return false;
|
426 | }
|
427 | if (typeof t !== 'number' || isNaN(t)) {
|
428 | return false;
|
429 | }
|
430 | if (typeof n !== 'number' || isNaN(n)) {
|
431 | return false;
|
432 | }
|
433 |
|
434 | if (n === 0) {
|
435 | return false;
|
436 | }
|
437 |
|
438 | lowerNumerator = (2 * y) + Math.pow(z, 2) - (z * Math.sqrt((4 * y * t / n) + Math.pow(z, 2)));
|
439 | upperNumerator = (2 * y) + Math.pow(z, 2) + (z * Math.sqrt((4 * y * t / n) + Math.pow(z, 2)));
|
440 | denominator = (2 * n) + (2 * Math.pow(z, 2));
|
441 |
|
442 | if (denominator === 0) {
|
443 | return false;
|
444 | }
|
445 |
|
446 | newUpper = upperNumerator / denominator;
|
447 | newLower = lowerNumerator / denominator;
|
448 |
|
449 | if (typeof newLower !== 'number' || isNaN(newLower)) {
|
450 | return false;
|
451 | }
|
452 | if (typeof newUpper !== 'number' || isNaN(newUpper)) {
|
453 | return false;
|
454 | }
|
455 |
|
456 | return {
|
457 | "upper": newUpper,
|
458 | "lower": newLower
|
459 | };
|
460 | }
|
461 |
|
462 | function _getChiSquared(a, b, c, d) {
|
463 | var chiSquaredNumerator;
|
464 | var chiSquaredDenominator;
|
465 | var chiSquared;
|
466 |
|
467 | var bigN = a + b + c + d;
|
468 |
|
469 | var nr1 = a + b;
|
470 | var nc1 = a + c;
|
471 | var nc2 = b + d;
|
472 | var nr2 = c + d;
|
473 |
|
474 | chiSquaredNumerator = bigN * Math.pow((Math.abs((a * d) - (b * c)) - (bigN / 2)), 2);
|
475 | chiSquaredDenominator = nr1 * nr2 * nc1 * nc2;
|
476 |
|
477 | chiSquared = chiSquaredNumerator / chiSquaredDenominator;
|
478 |
|
479 | if (typeof chiSquared !== 'number' || isNaN(chiSquared)) {
|
480 | return false;
|
481 | }
|
482 |
|
483 | return chiSquared;
|
484 | }
|
485 |
|
486 | function _getPValue(chiVal) {
|
487 | if (typeof chiVal !== 'number' || isNaN(chiVal)) {
|
488 | return false;
|
489 | }
|
490 |
|
491 | return 1 - chiSquared.cdf(chiVal, 1);
|
492 | }
|
493 |
|
494 | function _getArr(a, b, c, d) {
|
495 | var arr;
|
496 |
|
497 | if (c + d === 0) {
|
498 | return false;
|
499 | }
|
500 | if (a + b === 0) {
|
501 | return false;
|
502 | }
|
503 |
|
504 | arr = (c / (c + d)) - (a / (a + b));
|
505 |
|
506 | if (typeof arr !== 'number' || isNaN(arr)) {
|
507 | return false;
|
508 | }
|
509 |
|
510 | return arr;
|
511 | }
|
512 |
|
513 | function _getArrConfidence(arr, a, b, c, d) {
|
514 | var u1Numerator, u1Denominator, u1;
|
515 | var u2Numerator, u2Denominator, u2;
|
516 | var w1Numerator, w1Denominator, w1;
|
517 | var w2Numerator, w2Denominator, w2;
|
518 |
|
519 | var nr1 = a + b;
|
520 | var nc1 = a + c;
|
521 | var nc2 = b + d;
|
522 | var nr2 = c + d;
|
523 |
|
524 | var newUpper, newLower;
|
525 |
|
526 | if (typeof arr !== 'number' || isNaN(arr)) {
|
527 | return false;
|
528 | }
|
529 |
|
530 | if (nr1 === 0 || nr2 === 0) {
|
531 | return false;
|
532 | }
|
533 |
|
534 | u1Numerator = (2 * c) + Math.pow(z, 2) + (z * Math.sqrt((4 * c * d / nr2) + Math.pow(z, 2)));
|
535 | u1Denominator = (2 * nr2) + (2 * Math.pow(z, 2));
|
536 |
|
537 | if (u1Denominator === 0) {
|
538 | return false;
|
539 | }
|
540 |
|
541 | u1 = u1Numerator / u1Denominator;
|
542 |
|
543 | u2Numerator = (2 * a) + Math.pow(z, 2) + (z * Math.sqrt((4 * a * b / nr1) + Math.pow(z, 2)));
|
544 | u2Denominator = (2 * nr1) + (2 * Math.pow(z, 2));
|
545 |
|
546 | if (u2Denominator === 0) {
|
547 | return false;
|
548 | }
|
549 |
|
550 | u2 = u2Numerator / u2Denominator;
|
551 |
|
552 | w1Numerator = (2 * c) + Math.pow(z, 2) - (z * Math.sqrt((4 * c * d / nr2) + Math.pow(z, 2)));
|
553 | w1Denominator = (2 * nr2) + (2 * Math.pow(z, 2));
|
554 |
|
555 | if (w1Denominator === 0) {
|
556 | return false;
|
557 | }
|
558 |
|
559 | w1 = w1Numerator / w1Denominator;
|
560 |
|
561 | w2Numerator = (2 * a) + Math.pow(z, 2) - (z * Math.sqrt((4 * a * b / nr1) + Math.pow(z, 2)));
|
562 | w2Denominator = (2 * nr1) + (2 * Math.pow(z, 2));
|
563 |
|
564 | if (w2Denominator === 0) {
|
565 | return false;
|
566 | }
|
567 |
|
568 | w2 = w2Numerator / w2Denominator;
|
569 |
|
570 | newLower = arr - (z * Math.sqrt((u2 * (1 - u2) / (a + b)) + (w1 * (1 - w1) / (c + d))));
|
571 | newUpper = arr + (z * Math.sqrt((u1 * (1 - u1) / (c + d)) + (w2 * (1 - w2) / (a + b))));
|
572 |
|
573 |
|
574 | if (typeof newLower !== 'number' || isNaN(newLower)) {
|
575 | return false;
|
576 | }
|
577 |
|
578 | if (typeof newUpper !== 'number' || isNaN(newUpper)) {
|
579 | return false;
|
580 | }
|
581 |
|
582 | return {
|
583 | "lower": newLower,
|
584 | "upper": newUpper
|
585 | };
|
586 | }
|
587 |
|
588 | function _getNnt(arr) {
|
589 | var nnt;
|
590 |
|
591 | if (typeof arr !== 'number' || isNaN(arr)) {
|
592 | return false;
|
593 | }
|
594 |
|
595 | if (arr === 0) {
|
596 | return false;
|
597 | }
|
598 |
|
599 | nnt = Math.floor10(1 / arr);
|
600 |
|
601 | if (typeof nnt !== 'number' || isNaN(nnt)) {
|
602 | return false;
|
603 | }
|
604 |
|
605 | return nnt;
|
606 | }
|
607 |
|
608 | function _getNntConfidence(arrConfidence) {
|
609 | var newUpper, newLower;
|
610 |
|
611 | if (typeof arrConfidence !== "object" || arrConfidence === null) {
|
612 | return false;
|
613 | }
|
614 |
|
615 | if (typeof arrConfidence['upper'] !== 'number' || isNaN(arrConfidence['upper'])) {
|
616 | return false;
|
617 | }
|
618 |
|
619 | if (typeof arrConfidence['lower'] !== 'number' || isNaN(arrConfidence['lower'])) {
|
620 | return false;
|
621 | }
|
622 |
|
623 | if (arrConfidence['upper'] === 0) {
|
624 | return false;
|
625 | }
|
626 |
|
627 | if (arrConfidence['lower'] === 0) {
|
628 | return false;
|
629 | }
|
630 |
|
631 | newUpper = Math.round10((1 / arrConfidence['upper']), -1);
|
632 | newLower = Math.round10((1 / arrConfidence['lower']), -1);
|
633 |
|
634 | if (typeof newUpper !== 'number' || isNaN(newUpper)) {
|
635 | return false;
|
636 | }
|
637 |
|
638 | if (typeof newLower !== 'number' || isNaN(newLower)) {
|
639 | return false;
|
640 | }
|
641 |
|
642 | return {
|
643 | "lower": newLower,
|
644 | "upper": newUpper
|
645 | };
|
646 | }
|
647 |
|
648 | module.exports = {
|
649 | getDiagnosticTest: getDiagnosticTest,
|
650 | getCaseControlStudy: getCaseControlStudy,
|
651 | getRct: getRct,
|
652 | getProspectiveStudy: getProspectiveStudy,
|
653 | getCoordinatesOfCurve: getCoordinatesOfCurve
|
654 | } |
\ | No newline at end of file |