Perform an operation on a vector using the previous value after the initial value

In Excel, it is easy to perform the calculation in the previous cell by referencing the previous cell. For example, starting with an initial value of 100 (step = 0), each next step will be 0.9 * previous + 9 simply by dragging the formula bar down from the first cell (step = 1). The next 10 steps will look like this:

  step value [1,] 0 100.00000 [2,] 1 99.00000 [3,] 2 98.10000 [4,] 3 97.29000 [5,] 4 96.56100 [6,] 5 95.90490 [7,] 6 95.31441 [8,] 7 94.78297 [9,] 8 94.30467 [10,] 9 93.87420 [11,] 10 93.48678 

I browsed the web pages and StackOverflow, and the best I could come up with was a for loop (below). Are there any more efficient ways to do this? Can a for loop be avoided? It seems that most functions in R (for example, cumsum , diff , apply , etc.) work on existing vectors instead of calculating new values ​​on the fly from the previous ones.

 #for loop. This works value <- 100 #Initial value for(i in 2:11) { current <- 0.9 * value[i-1] + 9 value <- append(value, current) } cbind(step = 0:10, value) #Prints the example output shown above 
+5
source share
2 answers

You seem to be looking for a way to do recursive calculations in R. Base R has two ways to do this, which differ in the form of the function used for recursion. Both methods can be used for your example.

Reduce can be used with recurrence equations of the form v[i+1] = function(v[i], x[i]) , where v is the computed vector and x input vector; those. when the output i+1 depends only on the i-th value of the calculated and input vectors, and the calculation performed using function(v, x) can be non-linear. It will be for you

  value <- 100 nout <- 10 # v[i+1] = function(v[i], x[i]) v <- Reduce(function(v, x) .9*v + 9, x=numeric(nout), init=value, accumulate=TRUE) cbind(step = 0:nout, v) 

filter used with recurrence equations of the form y[i+1] = x[i] + filter[1]*y[i-1] + ... + filter[p]*y[ip] , where y is the calculated vector and x input vector; that is, when the output can depend linearly on the delayed values ​​of the calculated vector, as well as on the i-th value of the input vector. For your case it will be:

  value <- 100 nout <- 10 # y[i+1] = x[i] + filter[1]*y[i-1] + ... + filter[p]*y[ip] y <- c(value, stats::filter(x=rep(9, nout), filter=.9, method="recursive", sides=1, init=value)) cbind(step = 0:nout, y) 

For both functions, the output length is determined by the length of the input vector x .
Both of these approaches give your result.

+10
source

Use our knowledge of the geometric series.

 i <- 0:10 0.9 ^ i * 100 + 9 * (0.9 ^ i - 1) / (0.9 - 1) #[1] 100.00000 99.00000 98.10000 97.29000 96.56100 95.90490 95.31441 94.78297 94.30467 93.87420 93.48678 
+9
source

Source: https://habr.com/ru/post/1244087/


All Articles