Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crossfilter average group

Im trying to calculate the average querytime by sum(querytimes) and then dividing them by a count.How can i get the count ?

var querytimeByMonthGroup = moveMonths.group().reduceSum(function (d) {
    return d.querytime;
});

var querytimeByMonthGroup = moveMonths.group().reduceSum(function (d) {
    return d.querytime / d.count; ???
});
like image 392
Pieter_Daems Avatar asked Mar 21 '13 14:03

Pieter_Daems


2 Answers

I think a better (and the intended) way to do this is by defining your own reduce functions (add, remove, initial). You can then store your running sum, count etc. within the reduce functions and adjust them as appropriate when the filters add & remove data from the group.

An example of doing this with averages and with min & max are given in this similar question: Using Crossfilter, is it possible to track max/min when grouping?

like image 195
Paul Young Avatar answered Nov 15 '22 13:11

Paul Young


I am not familiar with crossfilter, only just started playing with it. There may be a better way, but this provides a way to compute the count for the dimension(s) used for the grouping (I am not 100% clear that d.count refers to the count for the dimension used for the grouping, use another grouping if required).

Example derived from the code available at: https://github.com/square/crossfilter/wiki/API-Reference

var payments = crossfilter([
    {date: "2011-11-14T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
    {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
    {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
    {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90, tip: 0, type: "tab"},
    {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"},
    {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90, tip: 0, type: "tab"},
    {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash"},
    {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"},
    {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"},
    {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90, tip: 0, type: "tab"},
    {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"},
    {date: "2011-11-14T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
]);

var paymentsByType = payments.dimension(function(d) { return d.type; }),
        paymentVolumeByType = paymentsByType.group(),
        counts = paymentVolumeByType.reduceCount().all(),
        countByType = {}; 

// what is returned by all is a pseudo-array. An object that behaves like an array. 
// Trick to make it a proper array
Array.prototype.slice.call(counts).forEach(function(d) { countByType[d.key] = d.value; })
var paymentVolumeByType = paymentVolumeByType.reduceSum(function(d, i) { 
    console.log(d.total, d.type, countByType[d.type])
    return d.total / countByType[d.type]; 
});
// accessing parentVolumeByType to cause the reduceSum function to be called
var topTypes = paymentVolumeByType.top(1);
like image 24
widged Avatar answered Nov 15 '22 13:11

widged