如何创建一个具有给定范围、四分位数和中位数的数字列表

How to create a list of numbers with given range, quartiles and median?

本文关键字:四分 中位数 列表 数字 创建 何创建 一个 范围      更新时间:2023-09-26

我有以下要求:

创建一个"列表"容器以容纳具有numValues数据的数据组,平均值、中位数和四分位间距。如果您希望数据元素按升序排列顺序通过–1表示极值、四分位数或中位数,如果您不要求它们是特定的值。例如:makelist(3,5,-1,8,-1,9,TRUE)将返回"5,8,9"两个四分位数都必须提供给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))

注意:不必担心sortData部分。

这些是用来生成测试问题的。因此,这些数字将被用来问:"下四分位数是什么?"等等。因此,只想创建一组具有已知极值、中值和四分位数性质的数字。

以下是检查四分位数的函数:

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];
         }

我希望这将提供足够的骨架,您可以根据自己的工作进行调整。事实上,你已经拥有了几乎所有的零件。

// 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

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

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

我们将把upper quartilelower quartile都放入列表中两次。最后,我们用median的副本来填充列表。如果没有明确给定任何值,我们可以任意选择一个有效的数字。