0

I have a dataset I'm working with that is buildings and electrical power use over time.

There are two aggregations on these buildings that are simple sums across the entire timespan and I have those written. They end up looking like:

var reducer = reductio();
// How much energy is used in the whole system
reducer.value("energy").sum(function (d) {
    return +d.Energy;
});

These work great.

The third aggregation, however, is giving me some trouble. I need to find the point that the sum of all the buildings is at its greatest. I need the max of the sum and the time it happened. I wrote:

reducer.value("power").sum(function (d) {
    return +d.Power;
}).max(function (d) {
    return +d.Power;
}).aliasProp({
    time: function (d, v) {
        return v.Timestamp;
    }
});

But, this is not necessarily the biggest power use. I'm pretty sure this returns the sum and the time when any individual building used the most power.

So if the power values were 1, 1, 1, 15. I would end up with 18, when there might be a different moment when the values were 5, 5, 5, 5 for a total of 20. The 20 is what I need.

I am at a loss for how to get the maximum of a sum. Any advice?

K.Tibbs
  • 1
  • 2

1 Answers1

1

Just to restate: You are grouping on time, so your group keys are time periods of some sort. What you want is to find the time period (group) for which power use is greatest.

If I'm right that this is what you want, then you would not do this in your reducer, but rather by sorting the groups. You can order groups by using the group.order method: https://github.com/crossfilter/crossfilter/wiki/API-Reference#group_order

// During group setup
group.order(function(p) { return p.power.sum; })

// Later, when you want to grab the top power group
group.top(1)

Reductio's max aggregation should just give you the maximum value that occurs within the group. So given a group with values 1,1,1,15, you would get back the value 15. It sounds like that's not what you want.

Hopefully I understood properly. If not, please comment. If you can put together an example with toy data that is public and where you can tell me what you would like to see vs what you are getting, I should be able to help out.

Update based on example:

So, what you want (based on the description in the example) is to find the maximum power usage for any given time within the selected time period. So you would do the following:

var timeDim = buildings.dimension(function(d) { return d.Timestamp })
var timeGrp = timeDim.group().reduceSum(function(d) { return d.Power })
var maxResults = timeGrp.top(1)

Whenever you want to find the max power usage time for your current filter, just call timeGrp.top(1) and the key of that group will be the time with the maximum power.

Note: Don't filter on timeDim as the filters on a dimension are not applied to groups defined on that dimension.

Here's an updated JSFiddle that writes out the maximum group to the console: https://jsfiddle.net/esjewett/1o3robm3/1/

Ethan Jewett
  • 6,002
  • 16
  • 25
  • When I set a time range I don't use group, I use the [Filter method](https://github.com/crossfilter/crossfilter/wiki/API-Reference#dimension_filter) on the crossfilter dimension. Is this an unadvisable approach? – K.Tibbs Apr 04 '17 at 01:54
  • So what are you grouping on? Sorry, that wasn't clear to me. Could you share a working example - that would probably help a lot. – Ethan Jewett Apr 04 '17 at 15:40
  • I am not grouping (or rather, I am using GroupAll() on the dimension). As I understand it, aggregations do not work across groups. I have the dataset, I filter it based on range of times, then I aggregatE the values. Energy, used as an example in the original post, needs to be a sum across the entire dataset within the filtered range. If I group the dimension, then I will have an Energy sum for each group and I will have to sum them manually. Is there something incorrect in my understanding? – K.Tibbs Apr 05 '17 at 17:27
  • Can you share an example of the data you have, a filter you might apply, and the output you would like to see? – Ethan Jewett Apr 05 '17 at 21:28
  • It would be hard to get data (breakpoints in multiple API calls, console the values, convert to JSON, merge the JSON, anonymize the data, etc) and it would be useless. This is an API question. The question & answer are the same regardless of the data. As stated, I filter by time: `dim.filter(function (d) { return d >= e.min && d <= e.max; });` (This is not exact code.) But filters just reduce the # of results, they don't change what code needs to be executed later. The OP stated I want: if the values were 1, 1, 1, 15. I'd get 18, another group might be 5, 5, 5, 5 getting 20. I want 20 – K.Tibbs Apr 05 '17 at 23:23
  • 1
    Then use fake/example data. Yes, I believe there is something you are misunderstanding and that we are talking past each other. The working example is to clarify the communication issue. Please do create an example. It really will help us help you. – Ethan Jewett Apr 06 '17 at 12:40
  • If I had a working example, I wouldn't be asking how to do it. But I have translated my original question from english to javascript https://jsfiddle.net/nr6ezsv2/1/ – K.Tibbs Apr 06 '17 at 17:07
  • Updated my answer. For future reference, the best way to ask these questions is usually to create a working example that gets as far as you can, then describe how what you are seeing in the example diverges from what you expect to see. That makes it both most clear and least time-consuming for those who are interested in answering your question. As you can see, as soon as you did this, it was quite clear to me what the problem was and was quite quick and easy for me to give you some guidance. – Ethan Jewett Apr 07 '17 at 01:04
  • Users are encouraged to make _general questions_ (of use to many users), such that Stack Overflow does not become a huge collection of one-off answers dependent on each individual project codebase. The answer was simple and I thank you for your time and effort, but I will continue to try and uphold the guidelines shown to me every time I post a question. – K.Tibbs Apr 11 '17 at 17:20