【问题标题】:purrr - how to apply recursively a function n_times over one valuepurrr - 如何在一个值上递归地应用函数 n_times
【发布时间】:2019-04-01 06:06:02
【问题描述】:

我想将函数 f() 应用于一个值 n 次。

例如,如果我想应用此功能 5 次,我会执行以下操作:

f(f(f(f(f(1)))))

有什么解决办法吗?

例如,一些函数 y 使得:

y( 1, f, 5)

【问题讨论】:

  • 一个相关问题:stackoverflow.com/questions/52954442/…(虽然没有 purrr 解决方案)
  • 我怀疑在这里使用 purrr 比简单循环有什么好处:v <- 1; for( i in 1:5) v <- f(v)

标签: r purrr


【解决方案1】:

这是使用purrr::reduce 的一种方式。这有点作弊(也许不是?)但似乎有效。在下面的演示中,我将 3 递归地添加到初始值 5 次 -

library(purrr)

x <- 1
n <- 5

rep(x, n+1) %>% reduce(function(x, y) x + 3)
# [1] 16

这是reduce 的文档-

.x 列表或原子向量。

.f 对于 reduce(),一个 2 参数函数。该函数将被传递 累加值作为第一个参数,“下一个”值作为 第二个参数。

根据设计,reduce 需要 xy 参数。虽然您必须将两者都传递给您的函数,但您可以选择不使用 y ,就像我所做的那样。这意味着您的函数仅递归地使用累积值。

可以使用purrr::accumulate查看中间步骤-

rep(x, n+1) %>% accumulate(function(x, y) x + 3)
# [1]  1  4  7 10 13 16

请注意,该函数未应用于第一个实例,这就是为什么您需要 rep 中的 n+1 才能获得正确的结果。

编辑 1: 这是上述逻辑的简化版本 -

reduce(1:n, function(x, y) x + 3, .init = x)
# [1] 16

accumulate(1:n, function(x, y) x + 3, .init = x)
# [1]  1  4  7 10 13 16

编辑 2: 这是一个类似但更简单的基本 R 解决方案 -

Reduce(function(x, y) x + 3, 1:n, init = x)
# [1] 16

【讨论】:

    【解决方案2】:

    可以使用purrr::map 并将其放入y 的循环中吗?

    f <- function(n) n^2 # or any other function of n
    
    y <- function(n, fun, k = 1) {
    
      x <- n
      for (i in 1:k) {
        x <- unlist(purrr::map(x, fun))
      }
    
      return(x)
    
    }
    
    # then to do f five times would be:
    y(1, f, 5)
    

    为了更健壮,您可能需要对参数进行一些错误处理。

    【讨论】:

      【解决方案3】:

      这是我找到的解决方案。它看起来有点冗长,但它确实有效。

        reduce(
             rerun(5, f), 
        compose)(1)
      

      【讨论】:

        猜你喜欢
        • 2019-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-19
        • 1970-01-01
        相关资源
        最近更新 更多