0

I want to run a function N times, with it's input being the output it produced in the last iteration. Here's a manual example (with N=3):

fun <- function(data) {
  x <- data$x
  y <- data$y
  
  new_x <- x+y
  new_y <- x*y
  
  list(x=new_x, y=new_y)
}


#Initialise:
data <- list(x=2,y=3)
#Run N times:
data <- fun(data)
data <- fun(data)
data <- fun(data)

Is there a simple/fast way to do this, without using slow loops?

Mich55
  • 93
  • 13

1 Answers1

1

Is there a simple/fast way to do this

Yes, this is a trivial loop:

N = 3
for(i in 1:N) {
  data = fun(data)
}

without using slow loops?

This is not slow.

Loops in R are slower than vectorized operations. However, since each iteration depends on the previous result, this cannot be vectorized. With R's JIT compilation, a for loop will likely be faster than common ways in R to hide loops, like *apply functions. And anyway, it's difficult to make most of the *apply functions update their inputs for successive iterations, as is needed here. (JIT compilation has been enabled by default for many years now.)

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • Thanks, I wasn't sure that something like `*apply` would be no better (since we're told to avoid loops if at all possible in R...) – Mich55 Feb 11 '21 at 03:28
  • 1
    "Avoid loops if at all possible in R" is dated and terrible advice. Yes, you should avoid loops *if there is a vectorized alternative*, but it's generally best to think of *apply functions as "loop hiding". There's still a loop, it's just not visible to you. It's nice to improve code readability in many cases. Sometimes it will be a bit faster. Sometimes it will be a bit slower. But unless what you're doing inside the loop is computationally trivial, doing it X times is a large fixed cost and the method of iteration is negligible in comparison. – Gregor Thomas Feb 11 '21 at 03:33
  • 1
    For more reading on this, I like [Is R's apply family more than syntactic sugar?](https://stackoverflow.com/q/2275896/903061) This question is 11 years old and the answers predate the JIT compilation that improved `for` loop performance. Even then, there wasn't really a clear answer to if *apply is faster or not - sometimes yes, sometimes no. – Gregor Thomas Feb 11 '21 at 03:36