3

Ideally I would like to make use of purrr's accumulate function or similar.

Let's say I want to make use of utils::combn function iteratively, and get all the intermediate results (ideally put inside a list of lists).

In example below, initially, parameter x = 4, thus m will be also 4 (but (x, m) could be (5, 5), (6, 6), ...). Then, after first loop, x will be previous result, whilst m goes down by one, iteratively until m = 2.

n1 <- combn(x = 4, m = 4, simplify = FALSE) 
n2 <- map(n1, ~ combn(.x, 3, simplify = FALSE)) 
n3 <- map(n2, ~ map(., ~ combn(.x, 2, simplify = FALSE)))

> n1
[[1]]
[1] 1 2 3 4


> n2
[[1]]
[[1]][[1]]
[1] 1 2 3

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

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

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

> n3
[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[1] 1 2

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

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


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

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

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


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

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

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


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

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

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

As you can imagine, I want to get all possible combinations, e.g.:

choose(4, 4) -> choose(result, 3) -> choose(result, 2).

How can I do this?

halfer
  • 19,824
  • 17
  • 99
  • 186
filemonPi
  • 65
  • 5

1 Answers1

4

You can use accumulate + map_depth:

combn_recur <- function(n) {
  accumulate(c(n, 0:(n-2)),
             ~ map_depth(.x, .y, combn, m = n-.y, simplify = FALSE))[-1]
}
all.equal(combn_recur(4), c(n1, n2, n3))
# TRUE

combn_recur(3)
# [[1]]
# [1] 1 2 3
# 
# [[2]]
# [[2]][[1]]
# [1] 1 2
# 
# [[2]][[2]]
# [1] 1 3
# 
# [[2]][[3]]
# [1] 2 3

combn_recur(2)
# [[1]]
# [1] 1 2

combn_recur(1)
# Error in .f(.x[[i]], ...) : n < m
Darren Tsai
  • 32,117
  • 5
  • 21
  • 51