1
\$\begingroup\$

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?

\$\endgroup\$
  • \$\begingroup\$ 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). \$\endgroup\$ – wvxvw Mar 31 '15 at 15:23
  • \$\begingroup\$ 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 ? \$\endgroup\$ – Cyril N. Mar 31 '15 at 15:30
  • \$\begingroup\$ 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. \$\endgroup\$ – 200_success Mar 31 '15 at 17:36
  • \$\begingroup\$ 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 :) \$\endgroup\$ – Cyril N. Mar 31 '15 at 19:03
  • \$\begingroup\$ Why 5? Shouldn't it be 16? @wvxvw \$\endgroup\$ – twoyoung Mar 31 '15 at 19:27
1
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.