如何创建给定范围,四分位数和中位数的数字列表?

时间:2014-10-15 03:39:24

标签: javascript algorithm math

我有以下要求:

  

创建"列表的功能"容器举行              具有numValues数据的数据组和范围,              分配的中位数和四分位数范围。如果是,则传递TRUE              您希望数据元素按升序排列              订购。传递-1表示极端,四分之一或者              中位数,如果您不要求它们是特定值。              例如:              makelist(3,5,-1,8,-1,9,TRUE)将返回" 5,8,9和#34;              必须将两个四分位值提供给makelist()              功能。如果不是,则忽略它们。

我有以下函数的开头(在JavaScript中)。我正在寻找一些帮助来找出这个四分位数部分(如何创建数字的扩展以满足四分位数要求)。



makelist = function(numValues, lowerExtreme, lowerQuartile, median, upperQuartile, upperExtreme, sortData) {
  if (lowerExtreme == -1) lowerExtreme = 0;
  if (upperExtreme == -1) upperExtreme = lowerExtreme + 100;

  var magnitude = upperExtreme - lowerExtreme, // 9 - 5 = 4
    quarter = magnitude * .25,
    midway = magnitude * .5,
    threeQuarters = magnitude * .75;

  quarter = lowerExtreme + quarter;
  midway = lowerExtreme + midway;
  threeQuarters = lowerExtreme + threeQuarters;

  if (lowerQuartile == -1) upperQuartile = quarter;
  if (upperQuartile == -1) lowerQuartile = threeQuarters
  if (median == -1) median = midway;

  var step = magnitude / (numValues - 1); // 4 / 3 =

  var quartet = {
    lowerExtreme: lowerExtreme,
    lower: [],
    lowerMid: [],
    upperMid: [],
    upper: []
  }

  var fill = function(list, lowerExtreme, upperExtreme) {
    var lastPush = null,
      step = (upperExtreme - lowerExtreme) / ((numValues) * .25);
    for (var i = lowerExtreme; i <= upperExtreme; i += step) {
      list.push(Math.round(i));
      lastPush = i;
    }
    return lastPush;
  }
  quartet.lowerExtreme = fill(quartet.lower, quartet.lowerExtreme, lowerQuartile, step) || quartet.lowerExtreme;
  console.info("quartet.lower: " + quartet.lower + " quartet.lowerExtreme: " + quartet.lowerExtreme);

  quartet.lowerExtreme = fill(quartet.lowerMid, quartet.lowerExtreme, median, step) || quartet.lowerExtreme; // lowerQuartile
  console.info("quartet.lowerMid: " + quartet.lowerMid);

  quartet.lowerExtreme = fill(quartet.upperMid, quartet.lowerExtreme, upperQuartile, step) || quartet.lowerExtreme; // median
  console.info("quartet.upperMid: " + quartet.upperMid);

  quartet.lowerExtreme = fill(quartet.upper, quartet.lowerExtreme, upperExtreme, step) || quartet.lowerExtreme;
  console.info("quartet.upper: " + quartet.upper);

  var list = [];
  list = list.concat(quartet.lower);
  list = list.concat(quartet.lowerMid);
  list = list.concat(quartet.upperMid);
  list = list.concat(quartet.upper);

  if (sortData) {
    return list;
  } else {
    return list; // assume this is shuffled
  }
}
alert(makelist(3, 5, -1, 8, -1, 9, true))
&#13;
&#13;
&#13;

注意:不必担心sortData部分。

这些用于生成测试问题。那么这些数字将用于询问:&#34;什么是下四分位数?&#34;等等。所以只想创建一组具有极值,中位数和四分位数的已知属性的数字。

这是检查四分位数的函数:

quartile: function(array, percent){ /** @param percent - pass 25 for lower quartile, 75 for upper, 50 for mean. Defaults to 50 */
             if (!percent) percent = 50;
             array = array.sort(function(a, b){return a-b});
             var n = Math.round(array.length * percent / 100);
             return array[n];
         }

2 个答案:

答案 0 :(得分:1)

首先,我们知道我们需要列表中的medianupper extremelower extreme。对于离散分布,没有普遍接受的四分位定义。我将假设使用以下定义:

使用median将有序数据集分成两半。不要将median包含在任何一半中。 lower quartile值是数据下半部分的中位数。 upper quartile值是数据上半部分的中位数。

我们会将upper quartilelower quartile两次放入列表中。最后,我们在列表中填写median的副本。如果未明确给出任何值,我们可以任意选择有效数字。

答案 1 :(得分:1)

我希望这会提供足够的骨架,你可以调整以适应你的工作。事实上,你已经拥有了几乎所有的部分。

// make quartiles
makelist = function(numValues, extrema,  quartiles, sortData) {
  var milestone_V = [extrema[0]];
  var milestone_N = [0];
  var q_size = numValues / (quartiles.length + 1); // because the givens do not include the extremes
  var accounted = 0;
  for ( var i = 0; i < quartiles.length; ++i ) { // easier to do with a filter!
    accounted = (i+1) * q_size; 
    if ( quartiles[i] !== -1 ) {
      milestone_V.push( quartiles[i] );
      milestone_N.push( Math.floor(accounted) );
    }
  }
  // tweak ranges for the last value
  milestone_N.push( numValues - 1 );
  milestone_V.push( extrema[1] );

  console.log("inputs:", "numValues=", numValues, "range=", extrema, "quartiles=", quartiles);
/*
  console.log("..", "milestone_V", milestone_V);
  console.log("..", "milestone_N", milestone_N);
*/
  function myfill (N, fillrange) {
    var count = Math.floor(N);
    if (count <= 0) return [];
    // fills [lower, upper)
    var res = [];
    var step = (fillrange[1] - fillrange[0]) / count;
    var v0 = fillrange[0];
    for (var i = 0; i < N; ++i) {
      var tmp = v0 + i * step;
      res.push(Math.round(tmp*1e3)/1000); // prints 3 dec digits, most of the time
    }
    //console.log("....fill range=", fillrange, "count=", count, "N=", N, "results=", res);
    return res;
  }

  // driver
  var outcome = [];
  for ( var qno = 1; qno < milestone_V.length; ++qno ) {
    var qrange = [ milestone_V[qno-1], milestone_V[qno] ];
    var howmany = milestone_N[qno] - milestone_N[qno-1];
    var tmp = myfill(howmany, qrange);
    outcome = outcome.concat(tmp);
  }
  outcome.push( extrema[1] );
  return outcome;
}

console.log( "=================")
var x = makelist(3, [5, 9], [-1, 8, -1], true);
console.log( "len=",x.length, "...", x.join(","));

console.log( "=================")
var x = makelist(22, [5, 9], [6, 8, 8.5], true);
console.log( "len=",x.length, "...", x.join(","));

console.log( "=================")
var x = makelist(21, [5, 9], [-1, 8, 8.5], true);
console.log( "len=",x.length, "...", x.join(","));

输出如下:

inputs: numValues= 3 range= [ 5, 9 ] quartiles= [ -1, 8, -1 ]
len= 3 ... 5,8,9
=================
inputs: numValues= 22 range= [ 5, 9 ] quartiles= [ 6, 8, 8.5 ]
len= 22 ... 5,5.2,5.4,5.6,5.8,6,6.333,6.667,7,7.333,7.667,8,8.1,8.2,8.3,8.4,8.5,8.6,8.7,8.8,8.9,9
=================
inputs: numValues= 21 range= [ 5, 9 ] quartiles= [ -1, 8, 8.5 ]
len= 21 ... 5,5.3,5.6,5.9,6.2,6.5,6.8,7.1,7.4,7.7,8,8.1,8.2,8.3,8.4,8.5,8.6,8.7,8.8,8.9,9