Home > Net >  Percentile for a value
Percentile for a value

Time:10-27

emphasized textGiven an array of numbers, I am looking to find the percentile of a given value.

I found this code here that seems to do what I need, but I was hoping I could get someone to explain this code to me step by step:

const percentile = (arr, val) =>
  (100 *
    arr.reduce(
      (acc, v) => acc   (v < val ? 1 : 0)   (v === val ? 0.5 : 0),
      0
    )) /
  arr.length;

// example
// percentile([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6); // 55

Update

Thanks everyone for your help. I found a Percentile formula that further helps me understand what the code is doing.

Formula:

Percentile = [L ( 0.5 x S ) / N] * 100

  • L = Number of below rank
  • S = Number of same rank
  • N = Total numbers

Based on my new understanding of the function, I find this a bit easier to read:

/**
 * **Percentile = ((L   ( 0.5 x S )) / N) * 100**
 * - L = Number of values **lower** than `value`
 * - S = Number of same rank
 * - N = Total numbers
 */
const percentile = (arr, value) => {
  const currentIndex = 0;
  const totalCount = arr.reduce((count, currentValue) => {
    if (currentValue < value) {
      return count   1; // add 1 to `count`
    } else if (currentValue === value) {
      return count   0.5; // add 0.5 to `count`
    }
    return count   0;
  }, currentIndex);
  return (totalCount * 100) / arr.length;
};

CodePudding user response:

The function is equivalent to ths simpler version.

count contains the number of elements that val is higher than, plus 0.5 for each element it's equal to. Dividing this total by the number of elements is the percentile.

const percentile = (arr, val) => {
  let count = 0;
  arr.forEach(v => {
    if (v < val) {
      count  ;
    } else if (v == val) {
      count  = 0.5;
    }
  });
  return 100 * count / arr.length;
}

console.log(percentile([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6));
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Even if the vector is not sorted the result is correct. The vector can contain duplicated values.

reduce scan a vector and produce a result accumulating partial results inside the acc

acc is initialized to 0 (line 5)

(v < val ? 1 : 0) result in 1 or 0 depending if v < val. The conditional ternary operator ? : is not needed because true is interpreted as 1 and false as 0, so you can write only (v < val)

(v === val ? 0.5 : 0) add .5 only for values equal to the val.

Lines 2 and 7 transform the frequency of lower (and equal) values into a percentile.

CodePudding user response:

Step-by-step explanation

  1. A constant named "percentile" is defined and passes two arguments, an array "arr" and a value "val", to the given function...
  2. The reduce() method is called on the array. This takes a function as an argument (called a reducer function), as well as an optional argument initialValue, which is defined here as 0 (zero).
  3. The reducer function creates an empty number variable "acc". The variable "v" refers to the current value, as taken from the array "arr".
  4. The reduce method iterates through each value in arr (aka it sets each element in arr as v). On each iteration...
  5. The reducer function compares v to val. If v is less than val, then acc is increased by 1. If v is equal to val, then acc is increased by 0.5. (In layperson's terms, this means that as the function iterates through each element in arr, the value of acc is counting how many elements are less than or equal to val.)
  6. After the function has iterated through every element of the array, acc is divided by the number of elements in arr. (In other words, since acc is the number of elements that are less than val, dividing acc/arr gives us a decimal representing the proportion of the array that's less than val.)
  7. That number is multiplied by 100 to turn the decimal into a percentage.
  • Related