Выбор квартиль стоимости по каждой точке - PullRequest
1 голос
/ 06 апреля 2020

Я строю оценку настроения твита за последние 10 лет. CSV-файл имеет три столбца, как показано ниже.

Я успешно построил каждое значение по дате. Однако, когда я попытался сгенерировать граф области, я столкнулся с проблемой, состоящей в том, что каждая дата имеет несколько значений.

Это потому, что каждая точка данных состоит из одного отдельного твита, в результате чего одна точка x имела несколько y значения.

Поэтому я попытался выбрать квартиль для каждой даты или выбрать наибольшее или наименьшее значение y. Для ясности см. Пример ниже.

enter image description here

8 января имеет несколько значений y (textblob)

Я хочу нарисовать область построить график, выбрав наибольшее значение или значение 2-го квартиля каждой точки.

Как выбрать только точку?

Я бы хотел указать точку в следующем коде как координату оси / у для линии или области greaph.

  function* vlinedrawing(data){
         for(let i;i<data.length;i++){
            if( i%500==0) yield svg.node();
            let px = margin+xscale(data[i].date)
            let py = height-margin-yscale(data[i].vader)
            paths.append('path')
            .attr('x',px)
            .attr('y',py)   
     }     
            yield svg.node()  
         }

Весь код находится по следующей ссылке.

https://jsfiddle.net/soonk/uh5djax4/2/

Заранее спасибо. (Причина, по которой это генератор, заключается в том, что я собираюсь визуализировать график анимированным способом)

1 Ответ

1 голос
/ 06 апреля 2020

Для получения 2-го квартиля вы можете использовать d3.quantile следующим образом:

d3.quantile(dataArray, 0.5);

Конечно, поскольку 2-й квартиль является медианой, вы также можете просто использовать:

d3.median(dataArray);

Но d3.quantile немного более универсален, вы можете просто изменить значение p для любого желаемого квартиля.

Используя ваши данные, без разбора дат (поэтому мы можно использовать Set для уникальных значений`), вот возможное решение:

const aggregatedData = [...new Set(data.map(function(d) {
    return d.date
}))].map(function(d) {
    return {
      date: parser(d),
      textblob: d3.quantile(data.filter(function(e) {
        return e.date === d
      }).map(function(e) {
        return e.textblob
      }), 0.5)
    }
});

Это просто быстрый ответ, который покажет вам путь: это не оптимизированный код, потому что есть несколько циклов внутри петель. Вы можете попытаться оптимизировать его.

Вот демоверсия:

var parser = d3.timeParse("%m/%d/%y");

d3.csv('https://raw.githubusercontent.com/jotnajoa/Javascript/master/tweetdata.csv', row).then(function(data) {

  const aggregatedData = [...new Set(data.map(function(d) {
    return d.date
  }))].map(function(d) {
    return {
      date: parser(d),
      textblob: d3.quantile(data.filter(function(e) {
        return e.date === d
      }).map(function(e) {
        return e.textblob
      }), 0.5)
    }
  });

  console.log(aggregatedData)

});

function row(d) {
  d.vader = +d.vader;
  d.textblob = +d.textblob;
  return d;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
...