If I have a vector as such:
dat <- c(1,2,3,4,5,19,20,21,56,80,81,92)
How can I break it up into a list as:
[[1]]
1 2 3 4 5
[[2]]
19 20 21
[[3]]
56
[[4]]
80 81
[[5]]
92
Just use split
in conjunction with diff
:
> split(dat, cumsum(c(1, diff(dat) != 1)))
$`1`
[1] 1 2 3 4 5
$`2`
[1] 19 20 21
$`3`
[1] 56
$`4`
[1] 80 81
$`5`
[1] 92
Not exactly what you asked for, but the "R.utils" package has a couple of related fun functions:
library(R.utils)
seqToIntervals(dat)
# from to
# [1,] 1 5
# [2,] 19 21
# [3,] 56 56
# [4,] 80 81
# [5,] 92 92
seqToHumanReadable(dat)
# [1] "1-5, 19-21, 56, 80-81, 92"
I think Robert Krzyzanowski is correct. So here is a tidyverse that involves placing the vector into a tibble (data frame).
library(tidyverse)
# library(dplyr)
# library(tidyr)
df <- c(1,2,3,4,5,19,20,21,56,80,81,92) %>%
tibble(dat = .)
# using lag()
df %>%
group_by(seq_id = cumsum(dat != lag(dat) + 1 | is.na(dat != lag(dat) + 1)) %>%
nest()
# using diff()
df %>%
group_by(seq_id = cumsum(c(1, diff(dat)) != 1)) %>%
nest()
Of course, you need not nest the resulting groups into list-columns, and can instead perform some kind of summary operation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With