admin管理员组

文章数量:1405337

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

I created a JSFiddle please take a look.

Can anybody drop a hint please?

UPDATE:

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.

Thank you

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

I created a JSFiddle please take a look.

Can anybody drop a hint please?

UPDATE:

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.

Thank you

Share Improve this question edited Aug 9, 2015 at 18:51 Gordon 20.2k4 gold badges39 silver badges77 bronze badges asked Mar 4, 2015 at 13:07 flightsearchflightsearch 792 silver badges10 bronze badges 4
  • If you only use the datetime, the only thing you can pute is the count (per week, per weekday, per month, per year etc.). You can't pute an average. – stallingOne Commented Mar 5, 2015 at 8:32
  • After a bit of thinking: the only thing I would need additionally is the number of days selected. Isn't that correct? So if I would create a dimension on the date how do I get the numbers of selected days... – flightsearch Commented Mar 5, 2015 at 9:58
  • Still not clear enough for me I'm afraid :/ Maybe explain from the data how you get to 40.3 and 35.4 – stallingOne Commented Mar 5, 2015 at 12:52
  • I've pletely revised my answer below, because I realized you're talking about a second-level aggregation, which is a bit more of a challenge. Probably too late, but I thought I'd give it another shot in case it helps someone else. – Gordon Commented Aug 9, 2015 at 18:52
Add a ment  | 

1 Answer 1

Reset to default 6

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

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 also makes this pretty easy: https://github./esjewett/reductio

EDIT: 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.

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};
    }
);    

Finally, we'll pute 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;
}

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.

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

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

本文标签: javascriptdcjs and crossfilter reduce average counts per day of weekStack Overflow