我有一个看起来像
的大型csvname 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);
但是这将输出未定义的总数。
答案 0 :(得分:1)
首先,问题中描述的输出不是您要查找的实际输出,这只是您希望CSV具有的结构,因此您可以获得所需的输出:d3.csv
与d3.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>