I want to apply a function f() to one value n times.
For example, if I wanted to apply this function 5 times, I'd do something like:
f(f(f(f(f(1)))))
Is there any purrr solution for that?
For example, some function y such that:
y( 1, f, 5)
I want to apply a function f() to one value n times.
For example, if I wanted to apply this function 5 times, I'd do something like:
f(f(f(f(f(1)))))
Is there any purrr solution for that?
For example, some function y such that:
y( 1, f, 5)
Here's one way using purrr::reduce. It's a bit of cheating (maybe not?) but seems to work. In the below demo I am recursively adding 3 to my initial value 5 times -
library(purrr)
x <- 1
n <- 5
rep(x, n+1) %>% reduce(function(x, y) x + 3)
# [1] 16
Here's the documentation for reduce -
.x A list or atomic vector.
.f For reduce(), a 2-argument function. The function will be passed the accumulated value as the first argument and the "next" value as the second argument.
By design reduce requires an x and y argument. While you must pass both to your function, you can choose not to use y like I have done. This means your function uses only the accumulated value recursively.
The intermediate steps can be seen using purrr::accumulate -
rep(x, n+1) %>% accumulate(function(x, y) x + 3)
# [1] 1 4 7 10 13 16
Notice that the function wasn't applied to the first instance and that's why you need n+1 in rep to get correct result.
EDIT 1: Here's a simplified version of above logic -
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
EDIT 2: Here's a similar but simpler base R solution -
Reduce(function(x, y) x + 3, 1:n, init = x)
# [1] 16
Could use purrr::map and put that in a loop in 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)
To make more robust you'd probably put some error handling in for the arguments.
This is the solution I have found. It looks a little verbose, but it works.
reduce(
rerun(5, f),
compose)(1)