dc.js和crossfilter减少一周中每天的平均计数 [英] dc.js and crossfilter reduce average counts per day of week

查看:64
本文介绍了dc.js和crossfilter减少一周中每天的平均计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难正确设置交叉过滤器组。

I am struggle to get my crossfilter groups set up right. Maybe someone can drop a hint!

我的数据结构或多或少看起来是这样的:

My datastructure looks more or less this way:

{datetime: "2014-01-01 20:00:00", id:1}
{datetime: "2014-01-01 22:21:08", id:2}
{datetime: "2014-01-02 12:00:23", id:3} etc...

该维度在日期时间上返回星期几:

The dimension is on datetime to return the day of week:

var weekdayDimension = ndx.dimension(function(d) {
    return new Date(d.datetime).getDay();
});

现在我在分组方面遇到了问题。我想要每个工作日的平均活动次数。到目前为止,我有(当然没有正确的答案)

Now I have problems with the grouping. I want the average count of events per weekday. So far I have (of course no correct)

var weekdayAvgGroup = weekdayDimension.group(function (d) {
    return d;
});

我想我不明白该分组到底在做什么……

I think I do not understand what that grouping is doing exactly...

我的目标是要绘制一些图表,例如:

My goal is to have some chart like:

Monday => Average 40.3 Events
Tuesday => Average 35.4 Events

我创建了 JSFiddle ,请看一下。

I created a JSFiddle please take a look.

任何人都可以删除提示吗?

Can anybody drop a hint please?

更新:

经过进一步思考,我可以在Date上创建维。我所要做的就是知道选择的天数,以便计算

After additional thinking I could create a dimension on the Date. All I would have to do is to know the number of days selected in order to calculate the

(total amount of events selected/number of selected days)

所以我需要计算日期维度上的组数。但也没有找到解决方案。

So I would need to count the number of groups on the date dimension. But haven't found the solution on this one either.

谢谢

推荐答案

带注释的股票示例显示了如何做平均:
http://dc-js.github.io /dc.js/docs/stock.html

The annotated stock example shows how to do averages: http://dc-js.github.io/dc.js/docs/stock.html

基本上,您将使用自定义的reduce函数,保持计数和总和,然后将总和除以

Basically you will use a custom reduce function, maintain a count and a sum, and divide the sum by the count (if the count is greater than zero) to get an average.

Reductio也很容易实现:
https://github.com/esjewett/reductio

Reductio also makes this pretty easy: https://github.com/esjewett/reductio

编辑:回顾一下这,我注意到您的意思是一周中每一天不同日期之间的总计数的平均值。

Looking back on this, I notice you mean the average of the aggregated counts, across the unique dates for each day of the week.

我知道为时已晚,但是由于我们得到了这些第二级汇总问题的数量相当大,我想我会回答这个问题,以防其他人受到帮助。

I know it's too late, but since we get a fair number of these "second-level aggregation" questions, I thought I'd answer this one, in case it helps someone else.

因此,我们的结果应将当天的数据一周,因此我们将相应地设置维度和分组:

So, our results should bin the data on the day of the week, so we'll set up our dimension and group accordingly:

// dimension on day of week
var dim1 = ndx.dimension(function(d) {
    return d[0].getDay();
});
// group on day of week
var grp1 = dim1.group().reduce(
    ... // what goes here?
);

但是我们如何进行第二级聚合?交叉过滤器已经可以有效地提供一周中每一天的所有条目。我们需要做的是计算每个唯一日期的条目。

But how do we do the second-level aggregation? Already crossfilter is going to give all the entries for each day of the week, efficiently. What we need to do is count the entries per unique date.

我们可以为此使用 d3.map 。我们将首先使用 d3.time.day 删除日期信息,然后使用 .getTime()得到一个可以索引的整数。然后 d3.map 创建所有星期一,所有星期二容器:

We can use d3.map for this. We'll first use d3.time.day to remove the time-of-day info, then use .getTime() to get an integer we can index on. Then d3.map creates the "all Mondays", "all Tuesdays" bins:

var grp1 = dim1.group().reduce(
    function(p, v) { // add
        var day = d3.time.day(v[0]).getTime();
        p.map.set(day, p.map.has(day) ? p.map.get(day) + 1 : 1);
        p.avg = average_map(p.map);
        return p;
    },
    function(p, v) { // remove
        var day = d3.time.day(v[0]).getTime();
        p.map.set(day, p.map.has(day) ? p.map.get(day) - 1 : 0);
        p.avg = average_map(p.map);
        return p;
    },
    function() { // init
        return {map: d3.map(), avg: 0};
    }
);    

最后,我们将计算 d3中所有bin的平均值。地图,具有以下功能:

Finally, we'll compute the average of all bins in the d3.map with this function:

function average_map(m) {
    var sum = 0;
    m.forEach(function(k, v) {
        sum += v;
    });
    return m.size() ? sum / m.size() : 0;
}

d3可能效率不高.map 每天添加一次,因此对 average_map 的调用可以移到 valueAccessor 我们将在图表中使用。我将其保留为练习。

It might not be so efficient to walk the d3.map every time a day is added, so the call to average_map could be moved into the valueAccessor we'll use in the chart. I'll leave that as an exercise.

这里是一个展示技巧的小提琴:
http://jsfiddle.net/gordonwoodhull/0woyhg3n/11/

Here is a fiddle demonstrating the technique: http://jsfiddle.net/gordonwoodhull/0woyhg3n/11/

并应用于原始小提琴:
http://jsfiddle.net/gordonwoodhull/pkh03azq/6/

And applied to the original fiddle: http://jsfiddle.net/gordonwoodhull/pkh03azq/6/

这篇关于dc.js和crossfilter减少一周中每天的平均计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆