In the groupBy method, the closure identifies what you want to group, the list items are obtained using the grouped value:
x.groupBy { it[0] } // map entries by patient number
estimated as
[1:[[1, 20.28], [1, 11.11]], 2:[[2, 4.60], [2, 3.68]]]
The collectEntries method tells how to make each map element look like, given that each input for collectEntries has a patient number for the key and a list of pairs for this key for the value. So
x.groupBy {it[0]}.collectEntries {[(it.key): it.value.sum {it[1]}]}
estimated as
[1:31.39, 2:8.28]
On average, there will be one patient
x.groupBy {it[0]}.collectEntries {[(it.key): it.value.sum {it[1]}/it.value.size()]}
evaluating the value of [1:15.695, 2:4.14]
The average value of the average values:
def avgs = [1:15.695, 2:4.14] def averageOfAverages = avgs.entrySet().sum {it.value} / avgs.size()
source share