crossfilter.js - 根据单独的维度从组中排除事实
crossfilter.js - exclude facts from group based on separate dimension
假设我要在 dc.js 散点图
中绘制以下交叉过滤器对象(简化)
var ndx = crossfilter([
{time: 0.5, counts: 8, direction: 1},
{time: 0.8, counts: 0, direction: -1},
{time: 1.0, counts: 8, direction: 1},
{time: 1.2, counts: 1, direction: -1},
{time: 1.8, counts: 10, direction: 1},
{time: 2.0, counts: 2, direction: -1},
{time: 2.2, counts: 14, direction: 1},
{time: 2.5, counts: 0, direction: -1},
...
]);
如何设置交叉滤波器以使输出向量为
x --> [0,1,2,...]
y --> [8,9,14,...] // (average of all "1" direction transition counts, per whole integer time)
目前我所拥有的来自
const timeDim = ndx.dimension(d => d.time);
const binwidth = 1;
const timeHist = timeDim
.group(d => {
return binwidth * Math.floor(d / binwidth);
})
.reduceCount(); // I believe this only gives sum, but haven't gotten to averaging yet
当我不关心排除 方向时,这会起作用:-1,所有这样做的尝试都破坏了我的交叉过滤器,例如
const timeSignalDim = ndx.dimension(d => {
if (d.direction === 1) {
return d.time;
}
});
基于
最终使用reducio...
const binwidth = 1;
const timeDim = ndx.dimension(d => d.time);
const timeSignalGroup = reductio()
.count(true)
.sum(d => d.counts)
.avg(true)
.filter(d => {
return d.direction === 1;
})(
timeDim.group(d => {
return binwidth * Math.floor(d / binwidth);
})
);
并通过 valueAccessor fxn 访问这些值
...
.valueAccessor(d => {
return d.value.avg;
})
很高兴接受任何更优雅的回答!
维度和组函数中的每个路径都必须 return 一个值,否则 Javascript 中的默认 return 值为 undefined
,即 can cause crossfilter to go off the deep end .
此外,无法拒绝维度或组键函数中的行。相反,您必须将拒绝的行减少到零:
const timeDim = ndx.dimension(d => d.time);
const binwidth = 1;
const timeHist = timeDim
.group(d => {
return binwidth * Math.floor(d / binwidth);
})
.reduceSum(d => d.direction > 0 ? 1 : 0);
这将计算所有正方向。相当于你回答中reductio的.filter()
.
Reductio 非常优雅,但只是为了比较,因为我在你发布答案之前就开始回答这个问题,所以计算平均值的直接交叉过滤器方法是
.reduce(
(p,v) => { // add
p.sum += v.counts;
p.count++;
return p;
},
(p,v) => { // remove
p.sum -= v.counts;
p.count--;
return p;
},
() => ({sum: 0, count: 0}));
读数值时告诉图表计算比率:
chart.valueAccessor(({value: {sum,count}}) => sum / count);
结合跳跃方向 < 0:
.reduce(
(p,v) => { // add
if(v.direction > 0) {
p.sum += v.counts;
p.count++;
}
return p;
},
(p,v) => { // remove
if(v.direction > 0) {
p.sum -= v.counts;
p.count--;
}
return p;
},
() => ({sum: 0, count: 0}));
同样,reductio 在底层做着几乎相同的事情。如果您想使用灵活的 EDSL 或直接使用 crossfilter,您可以选择。
假设我要在 dc.js 散点图
中绘制以下交叉过滤器对象(简化)var ndx = crossfilter([
{time: 0.5, counts: 8, direction: 1},
{time: 0.8, counts: 0, direction: -1},
{time: 1.0, counts: 8, direction: 1},
{time: 1.2, counts: 1, direction: -1},
{time: 1.8, counts: 10, direction: 1},
{time: 2.0, counts: 2, direction: -1},
{time: 2.2, counts: 14, direction: 1},
{time: 2.5, counts: 0, direction: -1},
...
]);
如何设置交叉滤波器以使输出向量为
x --> [0,1,2,...]
y --> [8,9,14,...] // (average of all "1" direction transition counts, per whole integer time)
目前我所拥有的来自
const timeDim = ndx.dimension(d => d.time);
const binwidth = 1;
const timeHist = timeDim
.group(d => {
return binwidth * Math.floor(d / binwidth);
})
.reduceCount(); // I believe this only gives sum, but haven't gotten to averaging yet
当我不关心排除 方向时,这会起作用:-1,所有这样做的尝试都破坏了我的交叉过滤器,例如
const timeSignalDim = ndx.dimension(d => {
if (d.direction === 1) {
return d.time;
}
});
基于
const binwidth = 1;
const timeDim = ndx.dimension(d => d.time);
const timeSignalGroup = reductio()
.count(true)
.sum(d => d.counts)
.avg(true)
.filter(d => {
return d.direction === 1;
})(
timeDim.group(d => {
return binwidth * Math.floor(d / binwidth);
})
);
并通过 valueAccessor fxn 访问这些值
...
.valueAccessor(d => {
return d.value.avg;
})
很高兴接受任何更优雅的回答!
维度和组函数中的每个路径都必须 return 一个值,否则 Javascript 中的默认 return 值为 undefined
,即 can cause crossfilter to go off the deep end .
此外,无法拒绝维度或组键函数中的行。相反,您必须将拒绝的行减少到零:
const timeDim = ndx.dimension(d => d.time);
const binwidth = 1;
const timeHist = timeDim
.group(d => {
return binwidth * Math.floor(d / binwidth);
})
.reduceSum(d => d.direction > 0 ? 1 : 0);
这将计算所有正方向。相当于你回答中reductio的.filter()
.
Reductio 非常优雅,但只是为了比较,因为我在你发布答案之前就开始回答这个问题,所以计算平均值的直接交叉过滤器方法是
.reduce(
(p,v) => { // add
p.sum += v.counts;
p.count++;
return p;
},
(p,v) => { // remove
p.sum -= v.counts;
p.count--;
return p;
},
() => ({sum: 0, count: 0}));
读数值时告诉图表计算比率:
chart.valueAccessor(({value: {sum,count}}) => sum / count);
结合跳跃方向 < 0:
.reduce(
(p,v) => { // add
if(v.direction > 0) {
p.sum += v.counts;
p.count++;
}
return p;
},
(p,v) => { // remove
if(v.direction > 0) {
p.sum -= v.counts;
p.count--;
}
return p;
},
() => ({sum: 0, count: 0}));
同样,reductio 在底层做着几乎相同的事情。如果您想使用灵活的 EDSL 或直接使用 crossfilter,您可以选择。