накопление d3 для каждого столбца csv - PullRequest
1 голос
/ 06 мая 2020

Я пытаюсь использовать d3.rollup для суммирования каждого столбца. data.csv выглядит так:

DateTime, A, B, C
2020/2/27 7:16  3   0   1
2020/2/26 23:44 1   0   4
2020/2/26 21:35 1   1   0
2020/2/26 15:14 1   0   3
2020/2/25 20:35 1   1   0
2020/2/25 16:10 1   0   3

Желаемый результат:

2020/2/27   3   0   1
2020/2/26   3   1   7
2020/2/25   2   1   3

Я хотел бы группировать свои данные на ежедневной основе. Я пытаюсь вложить данные, используя d3.nest, но не могу сопоставить данные в каждом столбце.

Я не хочу вызывать столбцы по имени, например d3.sum(d.A). Вместо этого я хочу сопоставить данные со всеми столбцами.

var nested = d3.nest()
  .key(function(c) {return parseDate(new Date(c.datetime)); })//parseDate 

Чтобы получить дату по месяцам:

.rollup(function(d){return {
  values: d3.sum(d.map(function(v) {
  return +v[d];}))};})
.entries(data);

Любая помощь будет принята с благодарностью. Я только начал с js и d3.

1 Ответ

0 голосов
/ 08 мая 2020

Я дам ответ с помощью vanilla js, и я постараюсь вернуться и дать ответ d3, как только прочту достаточно документов.

Вы можете сделать это так:

csv:

DateTime, A, B, C
2020/2/27 7:16,  3,   0,   1
2020/2/26 23:44, 1,   0,   4
2020/2/26 21:35, 1,   1,   0
2020/2/26 15:14, 1,   0,   3
2020/2/25 20:35, 1,   1,   0
2020/2/25 16:10, 1,   0,   3

Что мы могли бы преобразовать в массив JSON / JavaScript разными способами, например:

Взято из: { ссылка }:

const csv2json = (str, delimiter = ',') => {
  const titles = str.slice(0, str.indexOf('\n')).split(delimiter);
  const rows = str.slice(str.indexOf('\n') + 1).split('\n');
  return rows.map(row => {
    const values = row.split(delimiter);
    return titles.reduce((object, curr, i) => (object[curr.trim()] = values[i].trim(), object), {})
  });
};


let csv =
`DateTime, A, B, C
2020/2/27 7:16,  3,   0,   1
2020/2/26 23:44, 1,   0,   4
2020/2/26 21:35, 1,   1,   0
2020/2/26 15:14, 1,   0,   3
2020/2/25 20:35, 1,   1,   0
2020/2/25 16:10, 1,   0,   3`;

let word_array = csv2json(csv,',');
console.log(word_array)
.as-console-wrapper { max-height: 100% !important; top: 0; }

JSON / JavaScript Массив:

[
  {
    "DateTime": "2020/2/27 7:16",
    "A": 3,
    "B": 0,
    "C": 1
  },
  {
    "DateTime": "2020/2/26 23:44",
    "A": 1,
    "B": 0,
    "C": 4
  },
  {
    "DateTime": "2020/2/26 21:35",
    "A": 1,
    "B": 1,
    "C": 0
  },
  {
    "DateTime": "2020/2/26 15:14",
    "A": 1,
    "B": 0,
    "C": 3
  },
  {
    "DateTime": "2020/2/25 20:35",
    "A": 1,
    "B": 1,
    "C": 0
  },
  {
    "DateTime": "2020/2/25 16:10",
    "A": 1,
    "B": 0,
    "C": 3
  }
]

Ответ на ваш вопрос (совокупные данные по дате):

  • используйте сокращение, чтобы создать объект с каждым днем ​​в качестве ключа (дата синтаксического анализа)
  • когда ключ уже существует, объедините значения на A, B, C
  • преобразовать объект в массив с Object.values

const myData = [{"DateTime":"2020/2/27 7:16","A":3,"B":0,"C":1},{"DateTime":"2020/2/26 23:44","A":1,"B":0,"C":4},{"DateTime":"2020/2/26 21:35","A":1,"B":1,"C":0},{"DateTime":"2020/2/26 15:14","A":1,"B":0,"C":3},{"DateTime":"2020/2/25 20:35","A":1,"B":1,"C":0},{"DateTime":"2020/2/25 16:10","A":1,"B":0,"C":3}];

const groupedData = Object.values(myData.reduce((aggObj, item) => {
  
  const dateOnly = new Date(item.DateTime).toLocaleDateString();
  
  if (aggObj.hasOwnProperty(dateOnly)){
    Object.entries(aggObj[dateOnly]).forEach(([key,val]) => {
      if (key != 'DateTime'){
        aggObj[dateOnly][key] = val + item[key];
      }
    });
  } else {
    aggObj[dateOnly] = {...item, "DateTime": dateOnly};
  }
  
  return aggObj;
  
}, {}));

console.log(groupedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...