dc.js 求和字段的平均值
dc.js average value over the summed field
我有以下数据数组:
ID Name Number
---- ------ --------
1 G 1
1 G 2
1 F 3
我想做下面的转换来计算平均值,但是我不知道怎么做。
ID Name Number_sum
---- ------ ------------
1 G 3
1 F 3
求和后求平均值
ID Number_avg
---- ------------
1 3
如果不预求和,则平均值计算错误:
ID Number_avg
---- ------------
1 2
我想计算每个 ID 的平均值,但偶数字段“姓名”。
接下来,我打算为每个ID建立一个图表。我有一个道路标识符 - 1。这条路由 2 部分组成:G 和 F。此外,G 部分又分为 2 个小部分,每个部分 1 公里和 2 公里。
如果我们考虑通常的平均值,那么我们会得到该值的最大部分(道路的一个子部分)的平均值。但是我想根据路段的平均值进行计算
<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js</title>
<meta charset="UTF-8">
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/d3.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/dc.js"></script>
</head>
<body>
<div id ="test"></div>
<script type="text/javascript">
//dc.js
var inlineND = new dc.NumberDisplay("#test");
//data
var array1 = [
{"ID": 1, "Name": "G", "Number": 1},
{"ID": 1, "Name": "G", "Number": 2},
{"ID": 1, "Name": "F", "Number": 3}
];
var make_calc = function() {
var ndx = crossfilter(array1), //
Dimension = ndx.dimension(function(d) {return d.ID;}),
DimensionGroup = Dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial);
function reduceAdd(p, v) {
++p.count;
p.total += v.Number;
return p;
}
function reduceRemove(p, v) {
--p.count;
p.total -= v.Number;
return p;
}
function reduceInitial() {
return {count: 0, total: 0};
}
inlineND
.group(DimensionGroup)
.valueAccessor(function(p) { return p.value.count > 0 ? p.value.total / p.value.count : 0; });
dc.renderAll();
//console.log(DimensionGroup);
};
make_calc();
</script>
</body>
</html>
我不确定,但你在找这样的东西吗?
const arr = [
{id: 1, name: 'G', number: 1},
{id: 2, name: 'G', number: 2},
{id: 3, name: 'F', number: 3}
]
const res = arr.reduce((acc, e) => {
const idx = acc.findIndex(x => x.name === e.name)
if (idx !== -1) {
acc[idx].number += e.number
} else {
acc.push(e)
}
return acc
}, [])
console.log(res)
我不知道我是否完全理解,但是如果你想按名称分组,求和,然后取所有组的平均值,你可以将你的维度放在名称上并使用正则 reduceSum
:
var ndx = crossfilter(array1), //
Dimension = ndx.dimension(function(d) {return d.Name;}),
DimensionGroup = Dimension.group().reduceSum(d => d.Number);
然后传递一个“fake groupAll”,其中returns组中的所有行到数字显示,并在值访问器中计算平均值:
.group({value: () => DimensionGroup.all()})
.valueAccessor(a => a.length === 0 ? 0 : d3.sum(a, ({value}) => value) / a.length);
<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js</title>
<meta charset="UTF-8">
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/d3.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/dc.js"></script>
</head>
<body>
<div id ="test"></div>
<script type="text/javascript">
//dc.js
var inlineND = new dc.NumberDisplay("#test");
//data
var array1 = [
{"ID": 1, "Name": "G", "Number": 1},
{"ID": 1, "Name": "G", "Number": 2},
{"ID": 1, "Name": "F", "Number": 3}
];
var make_calc = function() {
var ndx = crossfilter(array1), //
Dimension = ndx.dimension(function(d) {return d.Name;}),
DimensionGroup = Dimension.group().reduceSum(d => d.Number);
inlineND
.group({value: () => DimensionGroup.all()})
.valueAccessor(a => a.length === 0 ? 0 : d3.sum(a, ({value}) => value) / a.length);
dc.renderAll();
//console.log(DimensionGroup);
};
make_calc();
</script>
</body>
</html>
为了计算平均值,考虑到“Name”字段,需要考虑这个字段在reduce函数中的唯一出现。结果,在计算平均值时,将值的总和除以“名称”字段中唯一值的数量
<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js</title>
<meta charset="UTF-8">
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/d3.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/dc.js"></script>
</head>
<body>
<div id ="test"></div>
<script type="text/javascript">
//dc.js
var inlineND = new dc.NumberDisplay("#test");
//data
var array1 = [
{"ID": 1, "Name": "G", "Number": 1},
{"ID": 1, "Name": "G", "Number": 2},
{"ID": 1, "Name": "F", "Number": 3}
];
var make_calc = function() {
var ndx = crossfilter(array1), //
Dimension = ndx.dimension(function(d) {return d.ID;}),
DimensionGroup = Dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial);
function reduceAdd(p, v) {
++p.count;
p.total += v.Number;
if(v.Name in p.Names){
p.Names[v.Name] += 1
}
else{
p.Names[v.Name] = 1;
p.Name_count++;
};
return p;
}
function reduceRemove(p, v) {
--p.count;
p.total -= v.Number;
p.Names[v.Name]--;
if(p.Names[v.Name] === 0){
delete p.Names[v.Name];
p.Name_count--;
};
return p;
}
function reduceInitial() {
return {count: 0, total: 0, Name_count: 0, Names: {}};
}
inlineND
.group(DimensionGroup)
.valueAccessor(function(p) { return p.value.Name_count > 0 ? p.value.total / p.value.Name_count : 0; });
dc.renderAll();
//console.log(DimensionGroup);
};
make_calc();
</script>
</body>
</html>
我有以下数据数组:
ID Name Number ---- ------ -------- 1 G 1 1 G 2 1 F 3
我想做下面的转换来计算平均值,但是我不知道怎么做。
ID Name Number_sum ---- ------ ------------ 1 G 3 1 F 3
求和后求平均值
ID Number_avg ---- ------------ 1 3
如果不预求和,则平均值计算错误:
ID Number_avg ---- ------------ 1 2
我想计算每个 ID 的平均值,但偶数字段“姓名”。
接下来,我打算为每个ID建立一个图表。我有一个道路标识符 - 1。这条路由 2 部分组成:G 和 F。此外,G 部分又分为 2 个小部分,每个部分 1 公里和 2 公里。
如果我们考虑通常的平均值,那么我们会得到该值的最大部分(道路的一个子部分)的平均值。但是我想根据路段的平均值进行计算
<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js</title>
<meta charset="UTF-8">
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/d3.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/dc.js"></script>
</head>
<body>
<div id ="test"></div>
<script type="text/javascript">
//dc.js
var inlineND = new dc.NumberDisplay("#test");
//data
var array1 = [
{"ID": 1, "Name": "G", "Number": 1},
{"ID": 1, "Name": "G", "Number": 2},
{"ID": 1, "Name": "F", "Number": 3}
];
var make_calc = function() {
var ndx = crossfilter(array1), //
Dimension = ndx.dimension(function(d) {return d.ID;}),
DimensionGroup = Dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial);
function reduceAdd(p, v) {
++p.count;
p.total += v.Number;
return p;
}
function reduceRemove(p, v) {
--p.count;
p.total -= v.Number;
return p;
}
function reduceInitial() {
return {count: 0, total: 0};
}
inlineND
.group(DimensionGroup)
.valueAccessor(function(p) { return p.value.count > 0 ? p.value.total / p.value.count : 0; });
dc.renderAll();
//console.log(DimensionGroup);
};
make_calc();
</script>
</body>
</html>
我不确定,但你在找这样的东西吗?
const arr = [
{id: 1, name: 'G', number: 1},
{id: 2, name: 'G', number: 2},
{id: 3, name: 'F', number: 3}
]
const res = arr.reduce((acc, e) => {
const idx = acc.findIndex(x => x.name === e.name)
if (idx !== -1) {
acc[idx].number += e.number
} else {
acc.push(e)
}
return acc
}, [])
console.log(res)
我不知道我是否完全理解,但是如果你想按名称分组,求和,然后取所有组的平均值,你可以将你的维度放在名称上并使用正则 reduceSum
:
var ndx = crossfilter(array1), //
Dimension = ndx.dimension(function(d) {return d.Name;}),
DimensionGroup = Dimension.group().reduceSum(d => d.Number);
然后传递一个“fake groupAll”,其中returns组中的所有行到数字显示,并在值访问器中计算平均值:
.group({value: () => DimensionGroup.all()})
.valueAccessor(a => a.length === 0 ? 0 : d3.sum(a, ({value}) => value) / a.length);
<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js</title>
<meta charset="UTF-8">
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/d3.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/dc.js"></script>
</head>
<body>
<div id ="test"></div>
<script type="text/javascript">
//dc.js
var inlineND = new dc.NumberDisplay("#test");
//data
var array1 = [
{"ID": 1, "Name": "G", "Number": 1},
{"ID": 1, "Name": "G", "Number": 2},
{"ID": 1, "Name": "F", "Number": 3}
];
var make_calc = function() {
var ndx = crossfilter(array1), //
Dimension = ndx.dimension(function(d) {return d.Name;}),
DimensionGroup = Dimension.group().reduceSum(d => d.Number);
inlineND
.group({value: () => DimensionGroup.all()})
.valueAccessor(a => a.length === 0 ? 0 : d3.sum(a, ({value}) => value) / a.length);
dc.renderAll();
//console.log(DimensionGroup);
};
make_calc();
</script>
</body>
</html>
为了计算平均值,考虑到“Name”字段,需要考虑这个字段在reduce函数中的唯一出现。结果,在计算平均值时,将值的总和除以“名称”字段中唯一值的数量
<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js</title>
<meta charset="UTF-8">
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/d3.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/dc.js"></script>
</head>
<body>
<div id ="test"></div>
<script type="text/javascript">
//dc.js
var inlineND = new dc.NumberDisplay("#test");
//data
var array1 = [
{"ID": 1, "Name": "G", "Number": 1},
{"ID": 1, "Name": "G", "Number": 2},
{"ID": 1, "Name": "F", "Number": 3}
];
var make_calc = function() {
var ndx = crossfilter(array1), //
Dimension = ndx.dimension(function(d) {return d.ID;}),
DimensionGroup = Dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial);
function reduceAdd(p, v) {
++p.count;
p.total += v.Number;
if(v.Name in p.Names){
p.Names[v.Name] += 1
}
else{
p.Names[v.Name] = 1;
p.Name_count++;
};
return p;
}
function reduceRemove(p, v) {
--p.count;
p.total -= v.Number;
p.Names[v.Name]--;
if(p.Names[v.Name] === 0){
delete p.Names[v.Name];
p.Name_count--;
};
return p;
}
function reduceInitial() {
return {count: 0, total: 0, Name_count: 0, Names: {}};
}
inlineND
.group(DimensionGroup)
.valueAccessor(function(p) { return p.value.Name_count > 0 ? p.value.total / p.value.Name_count : 0; });
dc.renderAll();
//console.log(DimensionGroup);
};
make_calc();
</script>
</body>
</html>