purrr - как рекурсивно применить функцию n_times над одним значением - PullRequest
0 голосов
/ 28 октября 2018

Я хочу применить функцию f () к одному значению n раз.

Например, если бы я хотел применить эту функцию 5 раз, я бы сделал что-то вроде:

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

Есть ли какое-нибудь мурлыканье для этого?

Например, некоторая функция y такая, что:

y( 1, f, 5)

Ответы [ 3 ]

0 голосов
/ 28 октября 2018

Вот один из способов использования 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 () - функция с двумя аргументами. Функция будет передана накопленное значение в качестве первого аргумента и «следующее» значение как второй аргумент.

По проекту reduce требуется аргумент x и y. Хотя вы должны передать обе функции, вы можете не использовать y, как я это сделал. Это означает, что ваша функция рекурсивно использует только накопленное значение.

Промежуточные шаги можно увидеть, используя purrr::accumulate -

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

Обратите внимание, что функция не была применена к первому экземпляру, и поэтому вам нужно n+1 в rep, чтобы получить правильный результат.

РЕДАКТИРОВАТЬ 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: Вот аналогичное, но более простое решение base R -

Reduce(function(x, y) x + 3, 1:n, init = x)
# [1] 16
0 голосов
/ 28 октября 2018

Это решение, которое я нашел.Выглядит немного многословно, но работает.

  reduce(
       rerun(5, f), 
  compose)(1)
0 голосов
/ 28 октября 2018

Можно использовать 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)

Чтобы сделать его более надежным, вы, вероятно, добавили бы некоторую обработку ошибок для аргументов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...