# Certainty of two comparative values (A/B results certainty)

I'm trying to output the percentage of certainty of two comparatives data.

Here's the resulting code:

/**
* Original code from https://vwo.com/js/significanceCalculator.js
*/
function calculatePValue (c_t, c_c, v_t, v_c) {
var d1 = 0.0498673470,
d2 = 0.0211410061,
d3 = 0.0032776263,
d4 = 0.0000380036,
d5 = 0.0000488906,
d6 = 0.0000053830;

var c_p = c_c / c_t;
var v_p = v_c / v_t;

var std_error = Math.sqrt((c_p * (1 - c_p) / c_t) + (v_p * (1 - v_p) / v_t));
var z_value = (v_p - c_p) / std_error;

var a = Math.abs(z_value);
var p_value = 1.0 + a * (d1 + a * (d2 + a * (d3 + a * (d4 + a * (d5 + a * d6)))));

p_value *= p_value;
p_value *= p_value;
p_value *= p_value;
p_value *= p_value;
p_value = 1.0 / (p_value + p_value);
if (z_value >= 0)
p_value = 1 - p_value;

if (p_value > 0.5)
p_value = 1 - p_value;

p_value = Math.round(p_value * 1000) / 1000;
return p_value;
}

function getPercentage(totalA, convA, totalB, convB) {
var p = calculatePValue(totalA, convA, totalB, convB);
if (p < 0,5) {
return 'B, with certainty of : ' + ((1-p)*100).toFixed(2) + '%';
} else {
return 'A, with certainty of : ' + (p*100).toFixed(2) + '%';
}
}


For example, if you try with:

getPercentage(1000, 120, 500, 90);


you'll get:

"B, with certainty of : 99.90%"

The code for calculating P was extracted from here. I simply took it as a percentage value to display either A or B is better.

What do you think? Is this ok?

• One small thing that nevertheless stands out: repeated multiplication of p_value can be replaced with Math.pow(p, 5). Also, all of these formulas have sum-over-number-of-observation form, which is better implemented using Array (this would make your code more generic and easier to understand). Commented Mar 31, 2015 at 15:23
• I don't think it would work because we add the multiplication every time. Try with the console, you'll see. Wichi part of the code you would translate into an array ? Commented Mar 31, 2015 at 15:30
• Your calculatePValue() function appears to be the same as the NormalP() function from vwo.com/js/significanceCalculator.js, with nicer formatting and variable names. I would consider it a derivative work that needs attribution in the code itself. Commented Mar 31, 2015 at 17:36
• By attribution, you mean specifying the source? It's indeed the code from vwo.com but here I didn't wanted to say I was the original author, just be sure the code was sure. I updated the code to include that part. If it's not what you meant, can you elaborate? thank you :) Commented Mar 31, 2015 at 19:03
• Why 5? Shouldn't it be 16? @wvxvw Commented Mar 31, 2015 at 19:27

The code below doesn't reproduce your code entirely, it just illustrates what I mentioned earlier in the comments:

function example() {
var values = [0.0498673470,
0.0211410061,
0.0032776263,
0.0000380036,
0.0000488906,
0.0000053830];
function sum(a, b) { return a + b; }
function sqdiff(a, b) { return (b - a) * (b - a); }
function avg(data) {
return data.reduce(sum) / data.length;
}
function curry(f) {
var args = [].slice.call(arguments);
args.shift();
return function () {
return f.apply(null, args.concat([].slice.call(arguments)));
};
}
function std(data) {
var a = avg(data);
return Math.sqrt(data.map(curry(sqdiff, a)).reduce(sum) /
data.length);
}
console.log("Standard deviation: " + std(values));
}


You, most likely, won't want to write functions like curry yourself though. There are libraries out there which already do such (and many more) useful things. I believe that Lodash already has one.