如何在apply系列函数中复用前一次迭代值以替代for循环?
Hey there! Let's break down why your apply-based code isn't matching the for loop, and how to fix it with the right functional programming tool.
The Root Cause
Your original for loop works because it updates the y vector in place—each step uses the already updated y[t-1] to calculate y[t]. But apply functions don't work this way: they process elements independently, using the original, unmodified version of y every time. That's why all your calculations after t=2 are using y[t-1] = 0 instead of the previous iteration's result.
The Right Tool: Reduce()
For sequential calculations that depend on the prior step's output, Reduce() is the perfect fit in the apply family. It's designed for cumulative iteration, passing the result of each step as input to the next.
Working Code
N <- 500; ro <- 0.6; a <- 1 set.seed(1) v <- ts(rnorm(N,0,1)) # Use Reduce to build the y sequence y <- Reduce( function(last_y, current_v) { a + ro * last_y + current_v }, x = v[-1], # Start with v[2] since y[1] is initialized to 0 init = 0, # Initial value y[1] = 0 accumulate = TRUE # Keep all intermediate results, not just the final one ) # Convert back to ts object to match original format y <- ts(y) # Check results head(y) # [1] 0.0000000 1.1836433 0.8745574 3.1200152 3.2015169 3.2304179 mean(y) # 2.549763 — exactly matches your for loop!
How This Works
- The first argument is the iteration function: it takes the last calculated
yvalue (last_y) and the currentvvalue, then returns the newyvalue using your formula. x = v[-1]: We skip the first element ofvbecausey[1]is already set to 0 (corresponding to the first position in your original code).init = 0: Sets the starting value fory[1].accumulate = TRUE: This is critical—it tellsReduce()to return every step's result, not just the final value, so we get the full time series instead of a single number.
Why Your Apply Code Failed
Let's look at your original apply attempt:
y <- c(y[1,], unlist(apply(as.matrix(2:500), 1, function(t) { y[t,] <- a + ro*y[t-1,] + v[t,] })))
When apply runs this anonymous function for each t, it's using the original y data frame every time. Even though you assign y[t,] inside the function, that change doesn't persist across iterations—each function call gets a fresh copy of the initial y (where all values after the first are 0). So every calculation after t=2 uses y[t-1] = 0, leading to wrong results.
Bonus: purrr::accumulate() (Tidyverse Alternative)
If you use the tidyverse, purrr::accumulate() is a more readable wrapper for this kind of cumulative iteration:
library(purrr) y <- accumulate( .x = v[-1], .f = function(last_y, current_v) a + ro * last_y + current_v, .init = 0 ) %>% ts() mean(y) # Still 2.549763
内容的提问来源于stack exchange,提问作者Erdogan CEVHER

