purrr – 如何递归应用具有变化参数的函数

huangapple go评论65阅读模式
英文:

purrr - how to apply recursively a function with changing arguments

问题

理想情况下,我想要利用purrraccumulate函数或类似的功能。

假设我想要迭代地使用utils::combn函数,并获取所有中间结果(最好放在一个列表的列表中)。

在下面的示例中,最初,参数x = 4,因此m也将是4(但(x, m)可以是(5, 5)(6, 6),...)。然后,在第一个循环之后,x将成为先前的结果,而m将逐渐减少,直到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)))

你可以想象,我想要获取所有可能的组合,例如:

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

我该如何实现这一点?

英文:

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 &lt;- combn(x = 4, m = 4, simplify = FALSE) 
n2 &lt;- map(n1, ~ combn(.x, 3, simplify = FALSE)) 
n3 &lt;- map(n2, ~ map(., ~ combn(.x, 2, simplify = FALSE)))

&gt; n1
[[1]]
[1] 1 2 3 4


&gt; 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

&gt; 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?

答案1

得分: 4

你可以使用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

(Note: The code remains in its original language as requested.)

英文:

You can use accumulate + map_depth:

combn_recur &lt;- 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 &lt; m

huangapple
  • 本文由 发表于 2023年2月18日 17:14:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75492316.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定