qesuite 1.0.51 → 1.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +235 -1
- package/dist/index.mjs +235 -1
- package/package.json +1 -1
- package/versions/1_0_52.md +1 -0
package/dist/index.d.mts
CHANGED
|
@@ -294,6 +294,20 @@ declare const Gamma: {
|
|
|
294
294
|
* @param x The value to be evaluated.
|
|
295
295
|
**/
|
|
296
296
|
Trigamma(x: number): number;
|
|
297
|
+
/**
|
|
298
|
+
* Evaluates the lower incomplete gamma function for the specified value.
|
|
299
|
+
* @customfunction
|
|
300
|
+
* @param n
|
|
301
|
+
* @param x
|
|
302
|
+
**/
|
|
303
|
+
LowerIncomplete(n: number, x: number): number;
|
|
304
|
+
/**
|
|
305
|
+
* Evaluates the upper incomplete gamma function for the specified value.
|
|
306
|
+
* @customfunction
|
|
307
|
+
* @param n
|
|
308
|
+
* @param x
|
|
309
|
+
**/
|
|
310
|
+
UpperIncomplete(n: number, x: number): number;
|
|
297
311
|
};
|
|
298
312
|
/** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
299
313
|
*/
|
|
@@ -340,6 +354,7 @@ declare const Distributions: {
|
|
|
340
354
|
inv(p: number, a: number, b: number): any;
|
|
341
355
|
};
|
|
342
356
|
ChiSq: {
|
|
357
|
+
pdf(x: number, df: number): number;
|
|
343
358
|
cdf(x: number, df: number): number;
|
|
344
359
|
RightTail(x: number, df: number): number;
|
|
345
360
|
};
|
|
@@ -1021,6 +1036,8 @@ declare const ANOVA: {
|
|
|
1021
1036
|
};
|
|
1022
1037
|
Multifactor: {
|
|
1023
1038
|
MainEffectsPlot(factors: any, response: any): HTMLCanvasElement;
|
|
1039
|
+
Table(factors: any, response: any): {};
|
|
1040
|
+
GLM(factors: any, response: any): {};
|
|
1024
1041
|
};
|
|
1025
1042
|
};
|
|
1026
1043
|
declare function SumSquaredDeviation(data: number[], referenceValue?: any): number;
|
package/dist/index.d.ts
CHANGED
|
@@ -294,6 +294,20 @@ declare const Gamma: {
|
|
|
294
294
|
* @param x The value to be evaluated.
|
|
295
295
|
**/
|
|
296
296
|
Trigamma(x: number): number;
|
|
297
|
+
/**
|
|
298
|
+
* Evaluates the lower incomplete gamma function for the specified value.
|
|
299
|
+
* @customfunction
|
|
300
|
+
* @param n
|
|
301
|
+
* @param x
|
|
302
|
+
**/
|
|
303
|
+
LowerIncomplete(n: number, x: number): number;
|
|
304
|
+
/**
|
|
305
|
+
* Evaluates the upper incomplete gamma function for the specified value.
|
|
306
|
+
* @customfunction
|
|
307
|
+
* @param n
|
|
308
|
+
* @param x
|
|
309
|
+
**/
|
|
310
|
+
UpperIncomplete(n: number, x: number): number;
|
|
297
311
|
};
|
|
298
312
|
/** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
299
313
|
*/
|
|
@@ -340,6 +354,7 @@ declare const Distributions: {
|
|
|
340
354
|
inv(p: number, a: number, b: number): any;
|
|
341
355
|
};
|
|
342
356
|
ChiSq: {
|
|
357
|
+
pdf(x: number, df: number): number;
|
|
343
358
|
cdf(x: number, df: number): number;
|
|
344
359
|
RightTail(x: number, df: number): number;
|
|
345
360
|
};
|
|
@@ -1021,6 +1036,8 @@ declare const ANOVA: {
|
|
|
1021
1036
|
};
|
|
1022
1037
|
Multifactor: {
|
|
1023
1038
|
MainEffectsPlot(factors: any, response: any): HTMLCanvasElement;
|
|
1039
|
+
Table(factors: any, response: any): {};
|
|
1040
|
+
GLM(factors: any, response: any): {};
|
|
1024
1041
|
};
|
|
1025
1042
|
};
|
|
1026
1043
|
declare function SumSquaredDeviation(data: number[], referenceValue?: any): number;
|
package/dist/index.js
CHANGED
|
@@ -937,6 +937,28 @@ var Gamma = {
|
|
|
937
937
|
**/
|
|
938
938
|
Trigamma(x) {
|
|
939
939
|
return 1 / x + 1 / (2 * (x ^ 2)) + 1 / (6 * (x ^ 3)) - 1 / (30 * (x ^ 5)) + 1 / (42 * (x ^ 7)) - 1 / (30 * (x ^ 9)) + 5 / (66 * (x ^ 11)) - 691 / (2730 * (x ^ 13)) + 15 / (6 * (x ^ 15));
|
|
940
|
+
},
|
|
941
|
+
/**
|
|
942
|
+
* Evaluates the lower incomplete gamma function for the specified value.
|
|
943
|
+
* @customfunction
|
|
944
|
+
* @param n
|
|
945
|
+
* @param x
|
|
946
|
+
**/
|
|
947
|
+
LowerIncomplete(n, x) {
|
|
948
|
+
return Gamma.fn(n) - Gamma.UpperIncomplete(n, x);
|
|
949
|
+
},
|
|
950
|
+
/**
|
|
951
|
+
* Evaluates the upper incomplete gamma function for the specified value.
|
|
952
|
+
* @customfunction
|
|
953
|
+
* @param n
|
|
954
|
+
* @param x
|
|
955
|
+
**/
|
|
956
|
+
UpperIncomplete(n, x) {
|
|
957
|
+
let expSum = 0;
|
|
958
|
+
for (let k = 0; k < n; k++) {
|
|
959
|
+
expSum += Math.pow(x, k) / Probability.Factorialize(k);
|
|
960
|
+
}
|
|
961
|
+
return Probability.Factorialize(n - 1) * Math.exp(-x) * expSum;
|
|
940
962
|
}
|
|
941
963
|
};
|
|
942
964
|
function NewtonRaphson(parameter, parameterizedFunction, derivativeFunction) {
|
|
@@ -1058,11 +1080,39 @@ var Distributions = {
|
|
|
1058
1080
|
}
|
|
1059
1081
|
},
|
|
1060
1082
|
ChiSq: {
|
|
1083
|
+
pdf(x, df) {
|
|
1084
|
+
let num = Math.pow(x, df / 2 - 1) * Math.exp(-x / 2);
|
|
1085
|
+
let den = Math.pow(2, df / 2) * Gamma.fn(df / 2);
|
|
1086
|
+
return num / den;
|
|
1087
|
+
},
|
|
1061
1088
|
cdf(x, df) {
|
|
1062
1089
|
if (df === 2) {
|
|
1063
1090
|
return 1 - Math.exp(-x / 2);
|
|
1064
1091
|
}
|
|
1065
|
-
|
|
1092
|
+
if (df % 2) {
|
|
1093
|
+
let test = 0;
|
|
1094
|
+
let stepCount = 1e7;
|
|
1095
|
+
let stepSize = x / stepCount;
|
|
1096
|
+
for (let i = 0; i < stepCount + 1; i++) {
|
|
1097
|
+
test += stepSize * Distributions.ChiSq.pdf(i * stepSize, df);
|
|
1098
|
+
}
|
|
1099
|
+
return test;
|
|
1100
|
+
if (x < df) {
|
|
1101
|
+
let y = Math.sqrt(df / 2) * Math.log(df / x);
|
|
1102
|
+
const aFunc = (c1, c2, c3, c4) => {
|
|
1103
|
+
return c1 + c2 * Math.pow(2 / df, 0.5) + c3 * (2 / df) + c4 * Math.pow(2 / df, 1 / 5);
|
|
1104
|
+
};
|
|
1105
|
+
let A = aFunc(0.5, 0.1323, 36e-4, -38e-4);
|
|
1106
|
+
let a1 = aFunc(0.1968, -0.0452, -0.0128, -0.0168);
|
|
1107
|
+
let a2 = aFunc(0.1152, -0.099, 0.0539, -0.0168);
|
|
1108
|
+
let a3 = aFunc(4e-4, 0.0442, -0.0866, 0.0398);
|
|
1109
|
+
let a4 = aFunc(0.0195, -0.0629, 0.0708, 0.0269);
|
|
1110
|
+
return A / Math.pow(1 + a1 * y + a2 * Math.pow(y, 2) + a3 * Math.pow(y, 3) + a4 * Math.pow(y, 4), 4);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
let num = Gamma.LowerIncomplete(df / 2, x / 2);
|
|
1114
|
+
let den = Gamma.fn(df / 2);
|
|
1115
|
+
return num / den;
|
|
1066
1116
|
},
|
|
1067
1117
|
RightTail(x, df) {
|
|
1068
1118
|
return 1 - Distributions.ChiSq.cdf(x, df);
|
|
@@ -2594,6 +2644,57 @@ function Sum(data) {
|
|
|
2594
2644
|
});
|
|
2595
2645
|
return sum;
|
|
2596
2646
|
}
|
|
2647
|
+
function SumSquareByGroups(groups, response) {
|
|
2648
|
+
let groupKeys = Object.keys(groups);
|
|
2649
|
+
let groupSets = [];
|
|
2650
|
+
let treatmentCount = 0;
|
|
2651
|
+
groupKeys.forEach((group) => {
|
|
2652
|
+
let set = new Set(groups[group]);
|
|
2653
|
+
groupSets.push(set);
|
|
2654
|
+
treatmentCount += set.size;
|
|
2655
|
+
});
|
|
2656
|
+
let placeFactors = [];
|
|
2657
|
+
groupSets.forEach((s, sI) => {
|
|
2658
|
+
if (sI === groupSets.length - 1) {
|
|
2659
|
+
placeFactors.push(1);
|
|
2660
|
+
} else {
|
|
2661
|
+
placeFactors.push(groupSets[sI + 1].size);
|
|
2662
|
+
}
|
|
2663
|
+
});
|
|
2664
|
+
let returnObject = {};
|
|
2665
|
+
let groupNObject = {};
|
|
2666
|
+
response[Object.keys(response)[0]].forEach((value, index) => {
|
|
2667
|
+
let indexer = [];
|
|
2668
|
+
groupKeys.forEach((k, kI) => {
|
|
2669
|
+
let currentKey = groups[k][index];
|
|
2670
|
+
groupSets[kI].forEach((s, sI) => {
|
|
2671
|
+
if (s === currentKey) {
|
|
2672
|
+
indexer.push(sI);
|
|
2673
|
+
}
|
|
2674
|
+
});
|
|
2675
|
+
});
|
|
2676
|
+
returnObject[JSON.stringify(indexer)] = 0;
|
|
2677
|
+
groupNObject[JSON.stringify(indexer)] = 0;
|
|
2678
|
+
});
|
|
2679
|
+
response[Object.keys(response)[0]].forEach((value, index) => {
|
|
2680
|
+
let indexer = [];
|
|
2681
|
+
groupKeys.forEach((k, kI) => {
|
|
2682
|
+
let currentKey = groups[k][index];
|
|
2683
|
+
groupSets[kI].forEach((s, sI) => {
|
|
2684
|
+
if (s === currentKey) {
|
|
2685
|
+
indexer.push(sI);
|
|
2686
|
+
}
|
|
2687
|
+
});
|
|
2688
|
+
});
|
|
2689
|
+
returnObject[JSON.stringify(indexer)] += value;
|
|
2690
|
+
groupNObject[JSON.stringify(indexer)] += 1;
|
|
2691
|
+
});
|
|
2692
|
+
let sumsq = 0;
|
|
2693
|
+
Object.keys(returnObject).forEach((k) => {
|
|
2694
|
+
sumsq += Math.pow(returnObject[k], 2) / groupNObject[k];
|
|
2695
|
+
});
|
|
2696
|
+
return sumsq;
|
|
2697
|
+
}
|
|
2597
2698
|
function Rang(data) {
|
|
2598
2699
|
let dataNumbers = data.map((d) => {
|
|
2599
2700
|
return Number(d);
|
|
@@ -3714,7 +3815,125 @@ var ANOVA = {
|
|
|
3714
3815
|
chartSet.width += 1e3;
|
|
3715
3816
|
chartSet.axis.y.tickOnly = true;
|
|
3716
3817
|
let graph = CreateSplitGraph(individualCharts, `Main Effects Plot of ${Object.keys(response)[0]}`, chartSet);
|
|
3818
|
+
console.log(graph);
|
|
3717
3819
|
return graph;
|
|
3820
|
+
},
|
|
3821
|
+
Table(factors, response) {
|
|
3822
|
+
let anovaTable = {};
|
|
3823
|
+
let factorKeys = Object.keys(factors);
|
|
3824
|
+
let responseKey = Object.keys(response)[0];
|
|
3825
|
+
let Ntotal = response[responseKey].length;
|
|
3826
|
+
let DFE = 1;
|
|
3827
|
+
let correctionFactor = Math.pow(Sum(response[responseKey]), 2) / Ntotal;
|
|
3828
|
+
factorKeys.forEach((f) => {
|
|
3829
|
+
let fSet = new Set(factors[f]);
|
|
3830
|
+
let Nf = fSet.size;
|
|
3831
|
+
let SS_f = 0;
|
|
3832
|
+
fSet.forEach((level) => {
|
|
3833
|
+
let levelTotal = 0;
|
|
3834
|
+
let levelN = 0;
|
|
3835
|
+
factors[f].forEach((v, j) => {
|
|
3836
|
+
if (v === level) {
|
|
3837
|
+
levelTotal += response[responseKey][j];
|
|
3838
|
+
levelN += 1;
|
|
3839
|
+
}
|
|
3840
|
+
});
|
|
3841
|
+
SS_f += Math.pow(levelTotal, 2) / levelN;
|
|
3842
|
+
});
|
|
3843
|
+
SS_f = SS_f - correctionFactor;
|
|
3844
|
+
anovaTable[f] = {
|
|
3845
|
+
DF: Nf - 1,
|
|
3846
|
+
SS: SS_f,
|
|
3847
|
+
MS: SS_f / (Nf - 1),
|
|
3848
|
+
F: void 0,
|
|
3849
|
+
p: void 0
|
|
3850
|
+
};
|
|
3851
|
+
DFE = DFE * Nf;
|
|
3852
|
+
});
|
|
3853
|
+
DFE = Ntotal - DFE;
|
|
3854
|
+
for (let i = 0; i < factorKeys.length - 1; i++) {
|
|
3855
|
+
let f_i_Set = new Set(factors[factorKeys[i]]);
|
|
3856
|
+
for (let j = i + 1; j < factorKeys.length; j++) {
|
|
3857
|
+
let f_j_Set = new Set(factors[factorKeys[j]]);
|
|
3858
|
+
let SS_subtotal = 0;
|
|
3859
|
+
f_i_Set.forEach((fi) => {
|
|
3860
|
+
f_j_Set.forEach((fj) => {
|
|
3861
|
+
let groupSum = 0;
|
|
3862
|
+
let groupN = 0;
|
|
3863
|
+
response[responseKey].forEach((val, index) => {
|
|
3864
|
+
if (factors[factorKeys[i]][index] === fi && factors[factorKeys[j]][index] === fj) {
|
|
3865
|
+
groupSum += val;
|
|
3866
|
+
groupN += 1;
|
|
3867
|
+
}
|
|
3868
|
+
});
|
|
3869
|
+
SS_subtotal += Math.pow(groupSum, 2) / groupN;
|
|
3870
|
+
});
|
|
3871
|
+
});
|
|
3872
|
+
SS_subtotal = SS_subtotal - correctionFactor;
|
|
3873
|
+
let iRow = anovaTable[factorKeys[i]];
|
|
3874
|
+
let jRow = anovaTable[factorKeys[j]];
|
|
3875
|
+
let fi_fj_DF = iRow.DF * jRow.DF;
|
|
3876
|
+
let fi_fj_SS = SS_subtotal - iRow.SS - jRow.SS;
|
|
3877
|
+
anovaTable[`${factorKeys[i]}*${factorKeys[j]}`] = { DF: fi_fj_DF, SS: fi_fj_SS, MS: fi_fj_SS / fi_fj_DF, F: void 0, p: void 0 };
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
let interactionSS_subtotal = SumSquareByGroups(factors, response) - correctionFactor;
|
|
3881
|
+
let fullInteractionDF = 1;
|
|
3882
|
+
let SSE = 0;
|
|
3883
|
+
factorKeys.forEach((source) => {
|
|
3884
|
+
fullInteractionDF = fullInteractionDF * anovaTable[source].DF;
|
|
3885
|
+
});
|
|
3886
|
+
Object.keys(anovaTable).forEach((source) => {
|
|
3887
|
+
interactionSS_subtotal = interactionSS_subtotal - anovaTable[source].SS;
|
|
3888
|
+
SSE += anovaTable[source].SS;
|
|
3889
|
+
});
|
|
3890
|
+
let fullInteractionName = factorKeys.join("*");
|
|
3891
|
+
anovaTable[fullInteractionName] = { DF: fullInteractionDF, SS: interactionSS_subtotal, MS: interactionSS_subtotal / fullInteractionDF, F: void 0, p: void 0 };
|
|
3892
|
+
SSE += interactionSS_subtotal;
|
|
3893
|
+
let SStotal = SumSquaredDeviation(response[responseKey], 0) - correctionFactor;
|
|
3894
|
+
SSE = SStotal - SSE;
|
|
3895
|
+
let MSE = SSE / DFE;
|
|
3896
|
+
Object.keys(anovaTable).forEach((source) => {
|
|
3897
|
+
let sourceF = anovaTable[source].MS / MSE;
|
|
3898
|
+
anovaTable[source].F = sourceF;
|
|
3899
|
+
anovaTable[source].p = Distributions.F.RightTail(sourceF, anovaTable[source].DF, DFE);
|
|
3900
|
+
});
|
|
3901
|
+
anovaTable["Error"] = { DF: DFE, SS: SSE, MS: MSE };
|
|
3902
|
+
anovaTable["Total"] = { DF: Ntotal - 1, SS: SStotal };
|
|
3903
|
+
return anovaTable;
|
|
3904
|
+
},
|
|
3905
|
+
GLM(factors, response) {
|
|
3906
|
+
let factorKeys = Object.keys(factors);
|
|
3907
|
+
let anovaTable = {};
|
|
3908
|
+
let responseKey = Object.keys(response)[0];
|
|
3909
|
+
let Ntotal = response[responseKey].length;
|
|
3910
|
+
let DFE = 1;
|
|
3911
|
+
let responseData = response[responseKey];
|
|
3912
|
+
factorKeys.forEach((k) => {
|
|
3913
|
+
let SS = 0;
|
|
3914
|
+
let levels = new Set(factors[k]);
|
|
3915
|
+
let groupedData = GroupData(factors[k], responseData);
|
|
3916
|
+
let descriptiveStats = {};
|
|
3917
|
+
let mean_0;
|
|
3918
|
+
Object.keys(groupedData).forEach((k2, k_i) => {
|
|
3919
|
+
let mean = Mean(groupedData[k2]);
|
|
3920
|
+
descriptiveStats[k2].mean = mean;
|
|
3921
|
+
descriptiveStats[k2].std = StDev.S(groupedData[k2]);
|
|
3922
|
+
descriptiveStats[k2].N = groupedData[k2].length;
|
|
3923
|
+
if (k_i === 0) {
|
|
3924
|
+
mean_0 = mean;
|
|
3925
|
+
groupedData[k2].forEach((d) => {
|
|
3926
|
+
SS += mean;
|
|
3927
|
+
});
|
|
3928
|
+
} else {
|
|
3929
|
+
groupedData[k2].forEach((d) => {
|
|
3930
|
+
SS += mean - Math.pow(mean - d, 2);
|
|
3931
|
+
});
|
|
3932
|
+
}
|
|
3933
|
+
});
|
|
3934
|
+
console.log(k, SS);
|
|
3935
|
+
});
|
|
3936
|
+
return anovaTable;
|
|
3718
3937
|
}
|
|
3719
3938
|
}
|
|
3720
3939
|
};
|
|
@@ -3742,6 +3961,21 @@ var Probability = {
|
|
|
3742
3961
|
}
|
|
3743
3962
|
}
|
|
3744
3963
|
};
|
|
3964
|
+
function GroupData(groupingArray, responseArray) {
|
|
3965
|
+
if (groupingArray.length != responseArray.length) {
|
|
3966
|
+
return { forEachGroup() {
|
|
3967
|
+
} };
|
|
3968
|
+
}
|
|
3969
|
+
let returnObj = {};
|
|
3970
|
+
let levels = new Set(groupingArray);
|
|
3971
|
+
levels.forEach((l) => {
|
|
3972
|
+
returnObj[l] = [];
|
|
3973
|
+
});
|
|
3974
|
+
for (let i = 0; i < groupingArray.length; i++) {
|
|
3975
|
+
returnObj[groupingArray[i]].push(responseArray[i]);
|
|
3976
|
+
}
|
|
3977
|
+
return returnObj;
|
|
3978
|
+
}
|
|
3745
3979
|
function CreateCanvas(width, height) {
|
|
3746
3980
|
let canvas = document.createElement("canvas");
|
|
3747
3981
|
canvas.height = height;
|
package/dist/index.mjs
CHANGED
|
@@ -845,6 +845,28 @@ var Gamma = {
|
|
|
845
845
|
**/
|
|
846
846
|
Trigamma(x) {
|
|
847
847
|
return 1 / x + 1 / (2 * (x ^ 2)) + 1 / (6 * (x ^ 3)) - 1 / (30 * (x ^ 5)) + 1 / (42 * (x ^ 7)) - 1 / (30 * (x ^ 9)) + 5 / (66 * (x ^ 11)) - 691 / (2730 * (x ^ 13)) + 15 / (6 * (x ^ 15));
|
|
848
|
+
},
|
|
849
|
+
/**
|
|
850
|
+
* Evaluates the lower incomplete gamma function for the specified value.
|
|
851
|
+
* @customfunction
|
|
852
|
+
* @param n
|
|
853
|
+
* @param x
|
|
854
|
+
**/
|
|
855
|
+
LowerIncomplete(n, x) {
|
|
856
|
+
return Gamma.fn(n) - Gamma.UpperIncomplete(n, x);
|
|
857
|
+
},
|
|
858
|
+
/**
|
|
859
|
+
* Evaluates the upper incomplete gamma function for the specified value.
|
|
860
|
+
* @customfunction
|
|
861
|
+
* @param n
|
|
862
|
+
* @param x
|
|
863
|
+
**/
|
|
864
|
+
UpperIncomplete(n, x) {
|
|
865
|
+
let expSum = 0;
|
|
866
|
+
for (let k = 0; k < n; k++) {
|
|
867
|
+
expSum += Math.pow(x, k) / Probability.Factorialize(k);
|
|
868
|
+
}
|
|
869
|
+
return Probability.Factorialize(n - 1) * Math.exp(-x) * expSum;
|
|
848
870
|
}
|
|
849
871
|
};
|
|
850
872
|
function NewtonRaphson(parameter, parameterizedFunction, derivativeFunction) {
|
|
@@ -966,11 +988,39 @@ var Distributions = {
|
|
|
966
988
|
}
|
|
967
989
|
},
|
|
968
990
|
ChiSq: {
|
|
991
|
+
pdf(x, df) {
|
|
992
|
+
let num = Math.pow(x, df / 2 - 1) * Math.exp(-x / 2);
|
|
993
|
+
let den = Math.pow(2, df / 2) * Gamma.fn(df / 2);
|
|
994
|
+
return num / den;
|
|
995
|
+
},
|
|
969
996
|
cdf(x, df) {
|
|
970
997
|
if (df === 2) {
|
|
971
998
|
return 1 - Math.exp(-x / 2);
|
|
972
999
|
}
|
|
973
|
-
|
|
1000
|
+
if (df % 2) {
|
|
1001
|
+
let test = 0;
|
|
1002
|
+
let stepCount = 1e7;
|
|
1003
|
+
let stepSize = x / stepCount;
|
|
1004
|
+
for (let i = 0; i < stepCount + 1; i++) {
|
|
1005
|
+
test += stepSize * Distributions.ChiSq.pdf(i * stepSize, df);
|
|
1006
|
+
}
|
|
1007
|
+
return test;
|
|
1008
|
+
if (x < df) {
|
|
1009
|
+
let y = Math.sqrt(df / 2) * Math.log(df / x);
|
|
1010
|
+
const aFunc = (c1, c2, c3, c4) => {
|
|
1011
|
+
return c1 + c2 * Math.pow(2 / df, 0.5) + c3 * (2 / df) + c4 * Math.pow(2 / df, 1 / 5);
|
|
1012
|
+
};
|
|
1013
|
+
let A = aFunc(0.5, 0.1323, 36e-4, -38e-4);
|
|
1014
|
+
let a1 = aFunc(0.1968, -0.0452, -0.0128, -0.0168);
|
|
1015
|
+
let a2 = aFunc(0.1152, -0.099, 0.0539, -0.0168);
|
|
1016
|
+
let a3 = aFunc(4e-4, 0.0442, -0.0866, 0.0398);
|
|
1017
|
+
let a4 = aFunc(0.0195, -0.0629, 0.0708, 0.0269);
|
|
1018
|
+
return A / Math.pow(1 + a1 * y + a2 * Math.pow(y, 2) + a3 * Math.pow(y, 3) + a4 * Math.pow(y, 4), 4);
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
let num = Gamma.LowerIncomplete(df / 2, x / 2);
|
|
1022
|
+
let den = Gamma.fn(df / 2);
|
|
1023
|
+
return num / den;
|
|
974
1024
|
},
|
|
975
1025
|
RightTail(x, df) {
|
|
976
1026
|
return 1 - Distributions.ChiSq.cdf(x, df);
|
|
@@ -2502,6 +2552,57 @@ function Sum(data) {
|
|
|
2502
2552
|
});
|
|
2503
2553
|
return sum;
|
|
2504
2554
|
}
|
|
2555
|
+
function SumSquareByGroups(groups, response) {
|
|
2556
|
+
let groupKeys = Object.keys(groups);
|
|
2557
|
+
let groupSets = [];
|
|
2558
|
+
let treatmentCount = 0;
|
|
2559
|
+
groupKeys.forEach((group) => {
|
|
2560
|
+
let set = new Set(groups[group]);
|
|
2561
|
+
groupSets.push(set);
|
|
2562
|
+
treatmentCount += set.size;
|
|
2563
|
+
});
|
|
2564
|
+
let placeFactors = [];
|
|
2565
|
+
groupSets.forEach((s, sI) => {
|
|
2566
|
+
if (sI === groupSets.length - 1) {
|
|
2567
|
+
placeFactors.push(1);
|
|
2568
|
+
} else {
|
|
2569
|
+
placeFactors.push(groupSets[sI + 1].size);
|
|
2570
|
+
}
|
|
2571
|
+
});
|
|
2572
|
+
let returnObject = {};
|
|
2573
|
+
let groupNObject = {};
|
|
2574
|
+
response[Object.keys(response)[0]].forEach((value, index) => {
|
|
2575
|
+
let indexer = [];
|
|
2576
|
+
groupKeys.forEach((k, kI) => {
|
|
2577
|
+
let currentKey = groups[k][index];
|
|
2578
|
+
groupSets[kI].forEach((s, sI) => {
|
|
2579
|
+
if (s === currentKey) {
|
|
2580
|
+
indexer.push(sI);
|
|
2581
|
+
}
|
|
2582
|
+
});
|
|
2583
|
+
});
|
|
2584
|
+
returnObject[JSON.stringify(indexer)] = 0;
|
|
2585
|
+
groupNObject[JSON.stringify(indexer)] = 0;
|
|
2586
|
+
});
|
|
2587
|
+
response[Object.keys(response)[0]].forEach((value, index) => {
|
|
2588
|
+
let indexer = [];
|
|
2589
|
+
groupKeys.forEach((k, kI) => {
|
|
2590
|
+
let currentKey = groups[k][index];
|
|
2591
|
+
groupSets[kI].forEach((s, sI) => {
|
|
2592
|
+
if (s === currentKey) {
|
|
2593
|
+
indexer.push(sI);
|
|
2594
|
+
}
|
|
2595
|
+
});
|
|
2596
|
+
});
|
|
2597
|
+
returnObject[JSON.stringify(indexer)] += value;
|
|
2598
|
+
groupNObject[JSON.stringify(indexer)] += 1;
|
|
2599
|
+
});
|
|
2600
|
+
let sumsq = 0;
|
|
2601
|
+
Object.keys(returnObject).forEach((k) => {
|
|
2602
|
+
sumsq += Math.pow(returnObject[k], 2) / groupNObject[k];
|
|
2603
|
+
});
|
|
2604
|
+
return sumsq;
|
|
2605
|
+
}
|
|
2505
2606
|
function Rang(data) {
|
|
2506
2607
|
let dataNumbers = data.map((d) => {
|
|
2507
2608
|
return Number(d);
|
|
@@ -3622,7 +3723,125 @@ var ANOVA = {
|
|
|
3622
3723
|
chartSet.width += 1e3;
|
|
3623
3724
|
chartSet.axis.y.tickOnly = true;
|
|
3624
3725
|
let graph = CreateSplitGraph(individualCharts, `Main Effects Plot of ${Object.keys(response)[0]}`, chartSet);
|
|
3726
|
+
console.log(graph);
|
|
3625
3727
|
return graph;
|
|
3728
|
+
},
|
|
3729
|
+
Table(factors, response) {
|
|
3730
|
+
let anovaTable = {};
|
|
3731
|
+
let factorKeys = Object.keys(factors);
|
|
3732
|
+
let responseKey = Object.keys(response)[0];
|
|
3733
|
+
let Ntotal = response[responseKey].length;
|
|
3734
|
+
let DFE = 1;
|
|
3735
|
+
let correctionFactor = Math.pow(Sum(response[responseKey]), 2) / Ntotal;
|
|
3736
|
+
factorKeys.forEach((f) => {
|
|
3737
|
+
let fSet = new Set(factors[f]);
|
|
3738
|
+
let Nf = fSet.size;
|
|
3739
|
+
let SS_f = 0;
|
|
3740
|
+
fSet.forEach((level) => {
|
|
3741
|
+
let levelTotal = 0;
|
|
3742
|
+
let levelN = 0;
|
|
3743
|
+
factors[f].forEach((v, j) => {
|
|
3744
|
+
if (v === level) {
|
|
3745
|
+
levelTotal += response[responseKey][j];
|
|
3746
|
+
levelN += 1;
|
|
3747
|
+
}
|
|
3748
|
+
});
|
|
3749
|
+
SS_f += Math.pow(levelTotal, 2) / levelN;
|
|
3750
|
+
});
|
|
3751
|
+
SS_f = SS_f - correctionFactor;
|
|
3752
|
+
anovaTable[f] = {
|
|
3753
|
+
DF: Nf - 1,
|
|
3754
|
+
SS: SS_f,
|
|
3755
|
+
MS: SS_f / (Nf - 1),
|
|
3756
|
+
F: void 0,
|
|
3757
|
+
p: void 0
|
|
3758
|
+
};
|
|
3759
|
+
DFE = DFE * Nf;
|
|
3760
|
+
});
|
|
3761
|
+
DFE = Ntotal - DFE;
|
|
3762
|
+
for (let i = 0; i < factorKeys.length - 1; i++) {
|
|
3763
|
+
let f_i_Set = new Set(factors[factorKeys[i]]);
|
|
3764
|
+
for (let j = i + 1; j < factorKeys.length; j++) {
|
|
3765
|
+
let f_j_Set = new Set(factors[factorKeys[j]]);
|
|
3766
|
+
let SS_subtotal = 0;
|
|
3767
|
+
f_i_Set.forEach((fi) => {
|
|
3768
|
+
f_j_Set.forEach((fj) => {
|
|
3769
|
+
let groupSum = 0;
|
|
3770
|
+
let groupN = 0;
|
|
3771
|
+
response[responseKey].forEach((val, index) => {
|
|
3772
|
+
if (factors[factorKeys[i]][index] === fi && factors[factorKeys[j]][index] === fj) {
|
|
3773
|
+
groupSum += val;
|
|
3774
|
+
groupN += 1;
|
|
3775
|
+
}
|
|
3776
|
+
});
|
|
3777
|
+
SS_subtotal += Math.pow(groupSum, 2) / groupN;
|
|
3778
|
+
});
|
|
3779
|
+
});
|
|
3780
|
+
SS_subtotal = SS_subtotal - correctionFactor;
|
|
3781
|
+
let iRow = anovaTable[factorKeys[i]];
|
|
3782
|
+
let jRow = anovaTable[factorKeys[j]];
|
|
3783
|
+
let fi_fj_DF = iRow.DF * jRow.DF;
|
|
3784
|
+
let fi_fj_SS = SS_subtotal - iRow.SS - jRow.SS;
|
|
3785
|
+
anovaTable[`${factorKeys[i]}*${factorKeys[j]}`] = { DF: fi_fj_DF, SS: fi_fj_SS, MS: fi_fj_SS / fi_fj_DF, F: void 0, p: void 0 };
|
|
3786
|
+
}
|
|
3787
|
+
}
|
|
3788
|
+
let interactionSS_subtotal = SumSquareByGroups(factors, response) - correctionFactor;
|
|
3789
|
+
let fullInteractionDF = 1;
|
|
3790
|
+
let SSE = 0;
|
|
3791
|
+
factorKeys.forEach((source) => {
|
|
3792
|
+
fullInteractionDF = fullInteractionDF * anovaTable[source].DF;
|
|
3793
|
+
});
|
|
3794
|
+
Object.keys(anovaTable).forEach((source) => {
|
|
3795
|
+
interactionSS_subtotal = interactionSS_subtotal - anovaTable[source].SS;
|
|
3796
|
+
SSE += anovaTable[source].SS;
|
|
3797
|
+
});
|
|
3798
|
+
let fullInteractionName = factorKeys.join("*");
|
|
3799
|
+
anovaTable[fullInteractionName] = { DF: fullInteractionDF, SS: interactionSS_subtotal, MS: interactionSS_subtotal / fullInteractionDF, F: void 0, p: void 0 };
|
|
3800
|
+
SSE += interactionSS_subtotal;
|
|
3801
|
+
let SStotal = SumSquaredDeviation(response[responseKey], 0) - correctionFactor;
|
|
3802
|
+
SSE = SStotal - SSE;
|
|
3803
|
+
let MSE = SSE / DFE;
|
|
3804
|
+
Object.keys(anovaTable).forEach((source) => {
|
|
3805
|
+
let sourceF = anovaTable[source].MS / MSE;
|
|
3806
|
+
anovaTable[source].F = sourceF;
|
|
3807
|
+
anovaTable[source].p = Distributions.F.RightTail(sourceF, anovaTable[source].DF, DFE);
|
|
3808
|
+
});
|
|
3809
|
+
anovaTable["Error"] = { DF: DFE, SS: SSE, MS: MSE };
|
|
3810
|
+
anovaTable["Total"] = { DF: Ntotal - 1, SS: SStotal };
|
|
3811
|
+
return anovaTable;
|
|
3812
|
+
},
|
|
3813
|
+
GLM(factors, response) {
|
|
3814
|
+
let factorKeys = Object.keys(factors);
|
|
3815
|
+
let anovaTable = {};
|
|
3816
|
+
let responseKey = Object.keys(response)[0];
|
|
3817
|
+
let Ntotal = response[responseKey].length;
|
|
3818
|
+
let DFE = 1;
|
|
3819
|
+
let responseData = response[responseKey];
|
|
3820
|
+
factorKeys.forEach((k) => {
|
|
3821
|
+
let SS = 0;
|
|
3822
|
+
let levels = new Set(factors[k]);
|
|
3823
|
+
let groupedData = GroupData(factors[k], responseData);
|
|
3824
|
+
let descriptiveStats = {};
|
|
3825
|
+
let mean_0;
|
|
3826
|
+
Object.keys(groupedData).forEach((k2, k_i) => {
|
|
3827
|
+
let mean = Mean(groupedData[k2]);
|
|
3828
|
+
descriptiveStats[k2].mean = mean;
|
|
3829
|
+
descriptiveStats[k2].std = StDev.S(groupedData[k2]);
|
|
3830
|
+
descriptiveStats[k2].N = groupedData[k2].length;
|
|
3831
|
+
if (k_i === 0) {
|
|
3832
|
+
mean_0 = mean;
|
|
3833
|
+
groupedData[k2].forEach((d) => {
|
|
3834
|
+
SS += mean;
|
|
3835
|
+
});
|
|
3836
|
+
} else {
|
|
3837
|
+
groupedData[k2].forEach((d) => {
|
|
3838
|
+
SS += mean - Math.pow(mean - d, 2);
|
|
3839
|
+
});
|
|
3840
|
+
}
|
|
3841
|
+
});
|
|
3842
|
+
console.log(k, SS);
|
|
3843
|
+
});
|
|
3844
|
+
return anovaTable;
|
|
3626
3845
|
}
|
|
3627
3846
|
}
|
|
3628
3847
|
};
|
|
@@ -3650,6 +3869,21 @@ var Probability = {
|
|
|
3650
3869
|
}
|
|
3651
3870
|
}
|
|
3652
3871
|
};
|
|
3872
|
+
function GroupData(groupingArray, responseArray) {
|
|
3873
|
+
if (groupingArray.length != responseArray.length) {
|
|
3874
|
+
return { forEachGroup() {
|
|
3875
|
+
} };
|
|
3876
|
+
}
|
|
3877
|
+
let returnObj = {};
|
|
3878
|
+
let levels = new Set(groupingArray);
|
|
3879
|
+
levels.forEach((l) => {
|
|
3880
|
+
returnObj[l] = [];
|
|
3881
|
+
});
|
|
3882
|
+
for (let i = 0; i < groupingArray.length; i++) {
|
|
3883
|
+
returnObj[groupingArray[i]].push(responseArray[i]);
|
|
3884
|
+
}
|
|
3885
|
+
return returnObj;
|
|
3886
|
+
}
|
|
3653
3887
|
function CreateCanvas(width, height) {
|
|
3654
3888
|
let canvas = document.createElement("canvas");
|
|
3655
3889
|
canvas.height = height;
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
- Rebuild of v1.0.51 see for details
|