'Function that splits numeric vector in the natural sequences it contains

I have a vector as the following:

example <- c(1, 2, 3, 8, 10, 11)

And I am trying to write a function that returns an output as the one you would get from:

desired_output <- list(first_sequence = c(1, 2, 3), 
                       second_sequence = 8, 
                       third_sequence = c(10, 11)
                       )

Actually, what I want is to count how many sequences as of those there are in my vector, and the length of each one. It just happens that a list as the one in "desired_ouput" would be sufficient.

The finality is to construct another vector, let's call it "b", that contains the following:

b <- c(3, 3, 3, 1, 2, 2)

The real world problem behind this is to measure the height of 3d objects contained in a 3D pointcloud.

I've tried to program both a function that returns the list in "example_list" and a recursive function that directly outputs vector "b", succeeded at none.

Someone has any idea? Thank you very much.



Solution 1:[1]

We can split to a list by creating a grouping by difference of adjacent elements

out <- split(example, cumsum(c(TRUE, abs(diff(example)) != 1)))

Then, we get the lengths and replicate

unname(rep(lengths(out), lengths(out)))
[1] 3 3 3 1 2 2

Solution 2:[2]

You could do:

out <- split(example, example - seq_along(example))

To get the lengths:

ln <- unname(lengths(out))
rep(ln, ln)
[1] 3 3 3 1 2 2

Solution 3:[3]

Here is one more. Not elegant but a different approach:

  1. Create a dataframe of the example vector
  2. Assign the elements to groups
  3. aggregate with tapply
example_df <- data.frame(example = example)

example_df$group <- cumsum(ifelse(c(1, diff(example) - 1), 1, 0))

tapply(example_df$example, example_df$group, function(x) x)
$`1`
[1] 1 2 3

$`2`
[1] 8

$`3`
[1] 10 11

Solution 4:[4]

One other option is to use ave:

ave(example, cumsum(c(1, diff(example) != 1)), FUN = length)
# [1] 3 3 3 1 2 2

#or just 
ave(example, example - seq(example), FUN = length)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 akrun
Solution 2 jay.sf
Solution 3 TarJae
Solution 4 Maël