Saya mencoba membuat plot kotak dengan kumis di d3plus, untuk membandingkan metrik antara penyedia "ini" dan penyedia "semua" di database saya. Saya telah menghitung ringkasan 5-statistik dari array yang sangat besar dalam tahap pra-pemrosesan, dan saya meneruskannya ke variabel data. Jika Anda menjalankan cuplikan terlampir (dimodifikasi dari d3plus contoh situs web), Anda dapat melihat caranya kode dan plotnya terlihat seperti. Namun, pada kenyataannya, ada beberapa outlier ekstrim dalam kategori "Semua", yang diberikan ke dalam kode saya sebagai baris komentar: 663373.22 untuk "maks" (untuk "Semua") dan -18427.39 untuk "min" (sekali lagi, untuk "Semua ").

Saya melihat ada mute metode yang dapat saya gunakan untuk .y, tetapi saya tidak yakin bagaimana saya akan membuatnya bekerja dengan suatu fungsi.

Apakah ada cara yang cukup mudah untuk "menekan" gambar outlier ekstrim ini (yang akan meruntuhkan kedua plot kotak menjadi garis datar jika diizinkan), atau outlier ekstrim apa pun yang, katakanlah, lebih tinggi dari (atau lebih rendah dari) beberapa kelipatan dari IQR?

<script src="//d3plus.org/js/d3.js"></script>
<script src="//d3plus.org/js/d3plus.js"></script>

<div id="viz"></div>

<script>
  var data = [
    {"provider": "This", "name":"min", "value": -1055.79},
    {"provider": "This", "name":"q1", "value": -172.819},
    {"provider": "This", "name":"med", "value": -46.795},
    {"provider": "This", "name":"q3", "value": 8.378},
    {"provider": "This", "name":"max", "value": 1033.15},
    {"provider": "All", "name":"min", "value": -1000},
    {"provider": "All", "name":"q1", "value": -111.60999999999999},
    {"provider": "All", "name":"med", "value": -13.92},
    {"provider": "All", "name":"q3", "value": 124.22},
    {"provider": "All", "name":"max", "value": 1000}
  ]
  //663373.22, -18427.39
  var visualization = d3plus.viz()
    .container("#viz")
    .data(data)
    .type("box")
    .id("name")
    .x("provider")
    .y("value")
    .ui([{ 
        "label": "Visualization Type",
        "method": "type", 
        "value": ["scatter","box"]
      }])
    .draw()
</script>
1
nvergos 10 November 2017, 20:45

1 menjawab

Jawaban Terbaik

Dari apa yang saya pahami tentang dokumen, mute digunakan sebagai kunci objek, di mana nilainya bisa berupa string, fungsi, atau array. Jadi jika Anda ingin membisukan semua titik data yang namanya q1, Anda harus melakukan .y({value:'value',mute:'q1'}).

Adapun solusinya, Anda memerlukan fungsi untuk menentukan outlier. Saya menemukan dan mengedit fungsi untuk mengembalikan rentang nilai yang dapat diterima (IQR * multiple), Anda dapat memodifikasi variabel multiple sesuai kebutuhan Anda. Kemudian Anda menggunakan fungsi sederhana isOutlier, untuk memeriksa apakah nilai yang diteruskan berada di luar rentang.

<script src="//d3plus.org/js/d3.js"></script>
<script src="//d3plus.org/js/d3plus.js"></script>

<div id="viz"></div>

<script>
  var data = [
    {"provider": "This", "name":"min", "value": -1055.79},
    {"provider": "This", "name":"q1", "value": -172.819},
    {"provider": "This", "name":"med", "value": -46.795},
    {"provider": "This", "name":"q3", "value": 8.378},
    {"provider": "This", "name":"max", "value": 1033.15},
    {"provider": "All", "name":"min", "value": -1000},
    {"provider": "All", "name":"q1", "value": -111.60999999999999},
    {"provider": "All", "name":"med", "value": -13.92},
    {"provider": "All", "name":"q3", "value": 124.22},
    {"provider": "All", "name":"max", "value": 1000}
  ]
 
  var outlierRange = outlierRange(data.map(d=>d.value))
  var isOutlier = val =>  (val < outlierRange[0] || val > outlierRange[1])

  //663373.22, -18427.39
  var visualization = d3plus.viz()
    .container("#viz")
    .data(data)
    .type("box")
    .id("name")
    .x("provider")
    .y({value:'value', mute: isOutlier })
    .ui([{ 
        "label": "Visualization Type",
        "method": "type", 
        "value": ["scatter","box"]
      }])
    .draw()
  
function outlierRange(someArray) {

  if(someArray.length < 4)
return someArray;

  let values, q1, q3, iqr, maxValue, minValue, multiple = 0.5;

  values = someArray.slice().sort( (a, b) => a - b);//copy array fast and sort

  if((values.length / 4) % 1 === 0){//find quartiles
q1 = 1/2 * (values[(values.length / 4)] + values[(values.length / 4) + 1]);
q3 = 1/2 * (values[(values.length * (3 / 4))] + values[(values.length * (3 / 4)) + 1]);
  } else {
q1 = values[Math.floor(values.length / 4 + 1)];
q3 = values[Math.ceil(values.length * (3 / 4) + 1)];
  }

  iqr = q3 - q1;
  maxValue = q3 + iqr * multiple;
  minValue = q1 - iqr * multiple;

  return [minValue, maxValue]
}




</script>
2
Eric Guan 10 November 2017, 22:24