6
$\begingroup$

Suppose that I have the following list called mylist:

mylist = {80.2, 80.3, 80.4, 327.6, 327.7, 327.8};

I would like to split mylist so that "runs of consecutive elements" are placed in the same sublist. Here, I will define two "consecutive elements" as real numbers that differ by 0.1. The second element can be either 0.1 greater than or 0.1 less than the first element, although in reality it makes more sense if the second element can only be 0.1 greater than the first element. (In my actual application, mylist is a list of times [i.e., elapsed time], in seconds, for example. My system is sampled every 0.1 seconds. Time never moves backwards, at least in my world!)

So the result I would like is:

{{80.2, 80.3, 80.4}, {327.6, 327.7, 327.8}}

I am thinking that SplitBy would be appropriate for this application:

SplitBy[list, f] splits list into sublists consisting of runs of successive elements that give the same value when f is applied.

However, in looking in the documentation, it is not clear to me how "adjacent elements" are defined. In Mathematica 7, "More Information" says:

SplitBy performs comparisons only on adjacent pairs elements.

Thus, what f do I use? I have tried:

SplitBy[mylist, #[[2]] - #[[1]] == 0.1 &]

and

SplitBy[mylist, #2 - #1 == 0.1 &]

but neither work. Does SplitBy define separate "slots" for the first and second element of a pair? Thanks for your time.

$\endgroup$
4
  • 1
    $\begingroup$ Possible duplicate: mathematica.stackexchange.com/q/4191/5 (only the test function is different) $\endgroup$
    – rm -rf
    Oct 2, 2012 at 21:55
  • 1
    $\begingroup$ @rm-rf I think is not a dupe in the sense that while SplitBy is mentioned in the question, it can not be used for cases such as this, and this question (or rather answers to it) will emphasize that. $\endgroup$ Oct 2, 2012 at 22:03
  • $\begingroup$ @LeonidShifrin You make a very good point. I never understood (or realized, rather) the difference between Split and SplitBy, and your answer helps me to learn this. Thanks. $\endgroup$
    – Andrew
    Oct 2, 2012 at 22:05
  • $\begingroup$ @LeonidShifrin Fair enough. I agree this is a useful question for why SplitBy cannot be used. $\endgroup$
    – rm -rf
    Oct 2, 2012 at 22:06

1 Answer 1

14
$\begingroup$

SplitBy is a wrong tool for the job here, because the condition you need couples adjacent elements in a way which can not be decoupled by applying some function to them. I would use

Split[mylist, Chop[#2 - #1 -  0.1] == 0 &]
$\endgroup$
3
  • $\begingroup$ Unfortunately, when I execute mylist = {80.2, 80.3, 80.4, 327.6, 327.7, 327.8}; SplitBy[mylist, Chop[#2 - #1 - 0.1] == 0 &], I get errors: Function::slotn: Slot number 2 in Chop[#2-#1-0.1]==0& cannot be filled from (Chop[#2-#1-0.1]==0&)[80.2] and so on for 80.3, 80.4, etc. Do you have any ideas? Thanks. $\endgroup$
    – Andrew
    Oct 2, 2012 at 21:57
  • 3
    $\begingroup$ @Andrew Please look carefully at the answer: I use Split, not SplitBy. SplitBy is a wrong tool for the job here, because the condition you need couples adjacent elements in a way which can not be decoupled by applying some function to them. $\endgroup$ Oct 2, 2012 at 22:00
  • $\begingroup$ Ah, sorry, I completely missed that. Your answer works perfectly! Thanks! $\endgroup$
    – Andrew
    Oct 2, 2012 at 22:03

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