Home > Mobile >  Function that splits numeric vector in the natural sequences it contains
Function that splits numeric vector in the natural sequences it contains

Time:04-27

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.

CodePudding user response:

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

CodePudding user response:

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

CodePudding user response:

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
  • Related