4
$\begingroup$

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?

$\endgroup$
8
  • $\begingroup$ Something like FindClusters[{{36, -244}, {37, -225}, {38, -197}, {48, -200}, {49, -181}, {50, -133}}, DistanceFunction -> (Abs[#1[[1]] - #2[[1]]] &)]? $\endgroup$ Apr 2, 2013 at 18:15
  • $\begingroup$ 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? $\endgroup$
    – R.S.
    Apr 2, 2013 at 18:28
  • $\begingroup$ Can you try finding a minimal example where you observe the bad clustering? $\endgroup$ Apr 2, 2013 at 18:30
  • $\begingroup$ Not sure if minimal, but FindClusters[{{36,-244.303},{37,-225.29},{38,-197.795},{48,-200.083},{49,-181.184},{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.561},{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]]]&)] $\endgroup$
    – R.S.
    Apr 2, 2013 at 18:42
  • $\begingroup$ @J.M. I believe that won't work because the distance function will not be applied to successive points but to the whole cluster $\endgroup$ Apr 2, 2013 at 19:14

1 Answer 1

4
$\begingroup$
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]

Mathematica graphics

$\endgroup$
4
  • $\begingroup$ 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]? $\endgroup$
    – R.S.
    Apr 2, 2013 at 18:57
  • $\begingroup$ 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! $\endgroup$
    – R.S.
    Apr 2, 2013 at 19:17
  • $\begingroup$ @R.S. Oh, yep, sorry. I already found it but forgot to edit. Doing that now $\endgroup$ Apr 2, 2013 at 19:19
  • $\begingroup$ Thank you all! Case closed I guess! :) $\endgroup$
    – R.S.
    Apr 2, 2013 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.