Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use use GroupBy and Sum together in Groovy?

Tags:

groovy

I have a collection as such:

[[patient1,value1], [patient2,value2]]

For Example.
x = [[1, 20.28], [1, 11.11], [2, 4.60], [2, 3.68]]

I use countBy to get the the counts per patient as such:

def counts = x.countBy{patient, value -> patient}

I'm trying to get the sums per patient with no luck:

def sums = x.groupBy({patient, value -> patient }).collectEntries{p, v -> p:v.sum()}

Is there something I'm missing?

Note: The overall goal here is to get the patient's average values which I use:

def avgs = sums.collect{patient, value -> (value / counts[patient]) }

Thanks!

like image 831
Zaccak Solutions Avatar asked Dec 21 '15 21:12

Zaccak Solutions


1 Answers

In the groupBy method the closure identifies what you want to group by, the list entries get filed under the grouped-by value:

x.groupBy { it[0] } // map entries by first entry in list (patient number)

evaluates to

[1:[[1, 20.28], [1, 11.11]], 2:[[2, 4.60], [2, 3.68]]]

The collectEntries method specifies what to make each map entry look like, given that each input to collectEntries has the patient number for a key and the list of pairs for that key for a value. So

x.groupBy {it[0]}.collectEntries {[(it.key): it.value.sum {it[1]}]}

evaluates to

[1:31.39, 2:8.28]

The average per patient would be

x.groupBy {it[0]}.collectEntries {[(it.key): it.value.sum {it[1]}/it.value.size()]}

evaluating to [1:15.695, 2:4.14]

For average of averages:

def avgs = [1:15.695, 2:4.14]
def averageOfAverages = avgs.entrySet().sum {it.value} / avgs.size()
like image 73
Nathan Hughes Avatar answered Nov 15 '22 09:11

Nathan Hughes