Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting all splits of numeric sequence in R

I'm trying to get all the possible splits of a sequence [1:n] in R. E.g.:

getSplits(0,3)

Should return all possible splits of the sequence 123, in other words (in a list of vectors):

[1] 1
[2] 1 2
[3] 1 2 3
[4] 1 3
[5] 2
[6] 2 3
[7] 3

Now I've created a function which does get to these vectors recursively, but having trouble combining them into one as above. My function is:

getSplits <- function(currentDigit, lastDigit, split) {
  splits=list();
  for (nextDigit in currentDigit: lastDigit)
  {
    currentSplit <- c(split, c(nextDigit));
    print(currentSplit);
    if(nextDigit < lastDigit) {
      possibleSplits = c(list(currentSplit), getSplits(nextDigit+1, lastDigit, currentSplit));
    }else{
      possibleSplits = currentSplit;
    }
    splits <- c(splits, list(possibleSplits));
  }
  return(splits);
} 

Where printing each currentSplit results in all the right vectors I need, but somehow the final returnt list (splits) nests them into deeper levels of lists, returning:

[1] 1

[[1]][[2]]
[[1]][[2]][[1]]
[1] 1 2

[[1]][[2]][[2]]
[1] 1 2 3


[[1]][[3]]
[1] 1 3


[[2]]
[[2]][[1]]
[1] 2

[[2]][[2]]
[1] 2 3


[[3]]
[1] 3

For the corresponding function call getSplits(1, 3, c()).

If anyone could help me out on getting this to work the way I described above, it'd be much appreciated!

like image 352
user2999349 Avatar asked Dec 13 '22 19:12

user2999349


1 Answers

character vector output

Try combn:

k <- 3
s <- unlist(lapply(1:k, combn, x = k, toString))
s
## [1] "1"       "2"       "3"       "1, 2"    "1, 3"    "2, 3"    "1, 2, 3"

data frame output

If you would prefer that the output be in the form of a data frame:

read.table(text = s, header = FALSE, sep = ",", fill = TRUE, col.names = 1:k)

giving:

  X1 X2 X3
1  1 NA NA
2  2 NA NA
3  3 NA NA
4  1  2 NA
5  1  3 NA
6  2  3 NA
7  1  2  3

list output

or a list:

lapply(s, function(x) scan(textConnection(x), quiet = TRUE, sep = ","))

giving:

[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 3

[[4]]
[1] 1 2

[[5]]
[1] 1 3

[[6]]
[1] 2 3

[[7]]
[1] 1 2 3

Update: Have incorporated improvement mentioned in comments as well as one further simplification and also added data frame and list output.

like image 170
G. Grothendieck Avatar answered Dec 18 '22 00:12

G. Grothendieck