I'm trying to split-up a vector to get all possible combinations of sub-sequences of numerically-contiguous elements.
Each permutation of the split needs to include all elements of the vector, and the relevant sequences will be those that fall in ascending order.
Here is an example of what I'm trying to describe:
# sample vector
x <- 1:3
# desired output
sets <- list(s1 = list(1, 2, 3), # x split into 3 vectors
s2 = list(1, 2:3), # x split into two vectors 1 vs 2:3
s3 = list(1:2, 3)) # x split into two vectors 1:2 vs 3
Coding this by hand-code works, but gets tedious when using longer vectors.
I am aware that there are ways to get all possible sub-sequences of a vector but I am having trouble seeing how I might split-up a vector to achieve these sets of subsequences. Any ideas?
Edit
To explain with greater precision, my example shows the output as having sets of different combinations list(s1, s2, s3)
. So the ideal output is a list-of-lists, and not just a single flat list of the possible combinations.
CodePudding user response:
You can try the code below using split
findInterval
combn
v <- seq_along(x)
Map(
split,
list(x),
unique(
lapply(
unlist(
sapply(
seq_along(v),
function(k) combn(v, k, simplify = FALSE)
),
recursive = FALSE
),
function(p) {
cumsum(duplicated(findInterval(v, p)))
}
)
)
)
Some example results
- For
x <- 1:3
, we obtain
[[1]]
[[1]]$`0`
[1] 1
[[1]]$`1`
[1] 2
[[1]]$`2`
[1] 3
[[2]]
[[2]]$`0`
[1] 1 2
[[2]]$`1`
[1] 3
[[3]]
[[3]]$`0`
[1] 1
[[3]]$`1`
[1] 2 3
[[4]]
[[4]]$`0`
[1] 1 2 3
- For
x <- 1:4
, we obtain
[[1]]
[[1]]$`0`
[1] 1
[[1]]$`1`
[1] 2
[[1]]$`2`
[1] 3
[[1]]$`3`
[1] 4
[[2]]
[[2]]$`0`
[1] 1 2
[[2]]$`1`
[1] 3
[[2]]$`2`
[1] 4
[[3]]
[[3]]$`0`
[1] 1
[[3]]$`1`
[1] 2 3
[[3]]$`2`
[1] 4
[[4]]
[[4]]$`0`
[1] 1
[[4]]$`1`
[1] 2
[[4]]$`2`
[1] 3 4
[[5]]
[[5]]$`0`
[1] 1 2 3
[[5]]$`1`
[1] 4
[[6]]
[[6]]$`0`
[1] 1 2
[[6]]$`1`
[1] 3 4
[[7]]
[[7]]$`0`
[1] 1
[[7]]$`1`
[1] 2 3 4
[[8]]
[[8]]$`0`
[1] 1 2 3 4
CodePudding user response:
I think that this will do the trick:
> x <- 1:4
> unlist(sapply(1:length(x), function(i)
combn(x, i, function(y)
as.list(as.data.frame(y)) )), recursive = F)
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
[[4]]
[1] 4
[[5]]
[1] 1 2
[[6]]
[1] 1 3
[[7]]
[1] 1 4
[[8]]
[1] 2 3
[[9]]
[1] 2 4
[[10]]
[1] 3 4
[[11]]
[1] 1 2 3
[[12]]
[1] 1 2 4
[[13]]
[1] 1 3 4
[[14]]
[1] 2 3 4
[[15]]
[1] 1 2 3 4