Crossfilter average group
Asked Answered
P

2

9

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; ???
});
Prickly answered 21/3, 2013 at 14:53 Comment(0)
P
2

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);
Patty answered 22/3, 2013 at 0:35 Comment(1)
The comment below is the intended way to achieve this.Awake
P
11

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?

Psalter answered 19/7, 2013 at 11:9 Comment(0)
P
2

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);
Patty answered 22/3, 2013 at 0:35 Comment(1)
The comment below is the intended way to achieve this.Awake

© 2022 - 2024 — McMap. All rights reserved.