3

Similar to Finding groups of contiguous numbers in a list and Find consecutive values in vector in R, the difference being I have a sequence of numbers that may be up to 4, ie

 y=c(4*1:4,24,31,33,39,4*16:20)
> y
 [1]  4  8 12 16 24 31 33 39 64 68 72 76 80

And I would like a function to return every sequence of values which are separated by a maximum of 4, so I get:

4 8 12 16 # all sep by at most 4
31 33 # all sep by at most 4
64 68 72 76 80 # all sep by at most 4

I tried:

st=c(1,which(diff(y)<5)+1)
en=c(st-1,length(y))
y[st]
[1]  4  8 12 16 33 68 72 76 80
y[en]
[1]  4  8 12 31 64 68 72 76 80

to no avail.

I am sure I am missing something obvious, and would appreciate any hints.

frank
  • 3,036
  • 7
  • 33
  • 65

2 Answers2

5

Is this what you're after?

split(y, cumsum(c(0, diff(y) > 4)));
#$`0`
#[1]  4  8 12 16
#
#$`1`
#[1] 24
#
#$`2`
#[1] 31 33
#
#$`3`
#[1] 39
#
#$`4`
#[1] 64 68 72 76 80

I don't see 24 in your list; is that a mistake?

If you want to exclude list entries with only one number, you can do everything in one line:

Filter(length, lapply(split(y, cumsum(c(0, diff(y) > 4))), function(x) x[length(x) > 1]));
#$`0`
#[1]  4  8 12 16
#
#$`2`
#[1] 31 33
#
#$`4`
#[1] 64 68 72 76 80
Maurits Evers
  • 49,617
  • 4
  • 47
  • 68
0

The requested result implied that you wanted to discard the values that were isolated:

> seqs <- split(y, cumsum( c(0, diff(y)>4) ) ); seqs[ sapply( seqs, length) > 1 ]
$`0`
[1]  4  8 12 16

$`2`
[1] 31 33

$`4`
[1] 64 68 72 76 80
IRTFM
  • 258,963
  • 21
  • 364
  • 487