# How do I group a nested list further according to a rule, and average selected elements?

I have a nested list of numbers like { {36, -244}, {37, -225}, {38, -197}, {48, -200}, {49, -181}, {50, -133} } which needs to be further nested into "bins" according to a rule. I would describe the rule like: Elements belong into one bin when their first sub-elements (36, 37, 38 vs. 48, 49, 50) can form a chain of successive integers or in other words, if arranged from lowest to highest there is no "hole" greater than 1 in the so formed bins. In the following step, how can I tell Mathematica to average the second sub-elements (-244, -225...) inside the former defined bins?

-
Something like FindClusters[{{36, -244}, {37, -225}, {38, -197}, {48, -200}, {49, -181}, {50, -133}}, DistanceFunction -> (Abs[#1[[1]] - #2[[1]]] &)]? – J. M. Apr 2 '13 at 18:15
Thank you for the fast reply! Your code works, but not if I replace the explicite list {{36... to -133}} with my original, larger one, that contains not only 2, but 19 "bins". What do I have to tweak? – R.S. Apr 2 '13 at 18:28
Can you try finding a minimal example where you observe the bad clustering? – J. M. Apr 2 '13 at 18:30
Not sure if minimal, but FindClusters[{{36,-244.303},{37,-225.29},{38,-197.795},{48,-200.083},{49,-181.18‌​4},{50,-133.752},{72,-290.859},{73,-247.223},{74,-195.386},{84,-233.914},{85,-209‌​.231},{86,-169.489},{96,-232.807},{97,-203.387},{98,-163.009},{108,-229.185},{109‌​,-206.779},{110,-163.368},{120,-241.064},{121,-204.68},{122,-165.54},{132,-244.56‌​1},{133,-210.368},{134,-167.645},{144,-235.07},{145,-204.954},{146,-164.355},{156‌​,-219.963},{157,-216.213},{158,-174.935},{168,-234.598},{169,-200.954},{170,-163.‌​93}},DistanceFunction->(Abs[#1[[1]]-#2[[1]]]&)] – R.S. Apr 2 '13 at 18:42
@J.M. I believe that won't work because the distance function will not be applied to successive points but to the whole cluster – Dr. belisarius Apr 2 '13 at 19:14

l =  {{36, -244}, {37, -225}, {38, -197}, {48, -200}, {49, -181}, {50, -133}};
l1 = Split[Sort @l, (#2[[1]] - #1[[1]] == 1 &)]
(*
{{{36, -244}, {37, -225}, {38, -197}},
{{48, -200}, {49, -181}, {50, -133}}}
*)


The second step

N /@ Mean /@ l1[[All, All, 2]]
(*{-222., -171.333}*)


Edit

For the larger dataset in your comment:

Graphics[{PointSize[Large], Pink, {Point@#, Green, Line@#} &@(Mean /@ l1),
Blue, Line /@ l1}, Axes -> True]


-
Thank you also! That code grouped even a larger dataset into correct bins. However, the second step yields results, but also one error per mean sounding like "Mean::rectt : Rectangular array expected at position 1 in Mean [..." Is this related to the [All,All,2]? – R.S. Apr 2 '13 at 18:57
Ok I got rid of the error by changing your code for the averaging to Mean /@l1[[All,All,2]]. Thanks that will save me days! – R.S. Apr 2 '13 at 19:17
@R.S. Oh, yep, sorry. I already found it but forgot to edit. Doing that now – Dr. belisarius Apr 2 '13 at 19:19
Thank you all! Case closed I guess! :) – R.S. Apr 2 '13 at 19:23