基于多行求和

时间:2019-09-24 19:53:38

标签: javascript database csv d3.js

我有一个看起来像

的大型csv
name      year     count
Sam       2012       3   
Mike      2012       4
Jeff      2013       5
.
.
.
Sam       2012       8  
Sam       2013       8       
Jeff      2013       9

如果姓名和年份相同,如何使用d3求和? 因此,输出应为

name year sum
Jeff 2013  14
Sam  2012  11
Sam  2013  8
Mike 2012  4

到目前为止,我已经尝试过了

var test = d3.nest()
    .key(function(d) { return d.name })
    .key(function(d) { return d.year })
    .rollup(function(v) { total: d3.sum(v, function(d) { return d.count }) })
    .object(data);

但是这将输出未定义的总数。

1 个答案:

答案 0 :(得分:1)

首先,问题中描述的输出不是您要查找的实际输出,这只是您希望CSV具有的结构,因此您可以获得所需的输出:d3.csvd3.csvParse(内部使用)一样,返回对象数组。这也适用于d3.tsv(问题中的CSV看起来像TSV ...幸运的是,这真的没关系,解决方案是CSV还是TSV都是一样的。)

话虽如此,请不要使用d3.nest,无论如何它很快就会被弃用。您也不能使用行函数,因为CSV中的每行都需要调用行函数。因此,最简单的选择是使用纯JavaScript解决方案来创建新的数据结构。

例如,使用reduce

const csv = `name,year,count
Sam,2012,3
Mike,2012,4
Jeff,2013,5
Sam,2012,8
Sam,2013,8
Jeff,2013,9`;

const data = d3.csvParse(csv, d3.autoType);

const newData = data.reduce(function(acc, curr) {
  const foundObject = acc.find(function(d) {
    return d.name === curr.name && d.year === curr.year;
  });
  if (foundObject) {
    foundObject.count += curr.count;
  } else {
    acc.push(curr)
  };
  return acc;
}, [])

console.log(newData);
<script src="https://d3js.org/d3.v5.min.js"></script>