-2

I am trying to create an R loop to help me get Var2, Var3, and Var4 (see output below). Var1, Var5 is pre-entered. Var41 is pre-entered.

 Var2 = lag(Var4) * Var5
 Var3 = Var2 + lag(Var3)
 Var4 = Var1 - Var3

Any suggestions?

enter image description here

alexsmith2
  • 331
  • 4
  • 12
  • For how many times? Only five times? – Taher A. Ghaleb Nov 06 '18 at 00:06
  • all the way to the length of var4 – alexsmith2 Nov 06 '18 at 00:15
  • 1
    Values for `Var2` do not seem to be consistent with `lag(Var4) * Var5`. Can you double-check? Also, `Var3` values are given by a recursive relation. In that case you'd need a starting value. What is that starting value? You state that you want to calculate values for `Var4` but then later mention that `Var4` is "pre-entered". So which one is it? – Maurits Evers Nov 06 '18 at 00:18
  • Hi @MauritsEvers, you are right. just fixed it. 500 is the starting value. – alexsmith2 Nov 06 '18 at 00:41
  • 1
    @ali.hash2 This still doesn't work. 500 as a starting value for `Var3` does not give the `Var3` values from your screenshot. Also, you haven't clarified on `Var4`. Is `Var4` given ("pre-entered") or are you trying to calculate `Var4`? In case of the latter you're having a cyclic condition, as `Var2` depends on `Var4`, `Var2` depends on `Var3`, and `Var3` depends again on `Var4`. – Maurits Evers Nov 06 '18 at 00:48
  • 1
    It would help *a lot* if you were to review how to provide a [minimal reproducible example/attempt](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). A screenshot of your data is not a good idea, as it (1) requires us to manually transcribe your data, and (2) it's not clear which quantities/columns you'd like to generate based on which other quantities/columns (what's input, what's output?). – Maurits Evers Nov 06 '18 at 00:50
  • Hi @MauritsEvers, Var1 is pre-entered -- it is not dependent on anything. The first row of Var4 is pre-entered at 500. The first row of Var2 and Var3 is 0. Second row of Var2 is 500 (lag(Var4)) times .1 (Var5). and Firstrow of Var3 is the sum of Var2 and lag(Var3). Then second row of Var4 is equal to Var1-Var3. – alexsmith2 Nov 06 '18 at 00:55
  • Oh. How could we know that the first values of Var2 and Var3 were pre-entered? :P – prosoitos Nov 06 '18 at 00:59

2 Answers2

2

First I pre-fill the table with initial values:

df <- data.frame(row = 1:5, 
                 Var1 = rep(500, 5),
                 Var2 = c(0, rep(NA_real_, 4)),
                 Var3 = c(0, rep(NA_real_, 4)),
                 Var4 = c(500, rep(NA_real_, 4)),
                 Var5 = 0.1)

Then, since this is recursive, I rerun this procedure, and each time it fills in one more row based on the availability of the prior row. (Probably not the most elegant, but it works!)

library(dplyr)
for(i in 2:nrow(df)) {
  df <- df %>%
    mutate(Var2 = if_else(row == 1,   0, lag(Var4) * Var5),
           Var3 = if_else(row == 1,   0, Var2 + lag(Var3)),
           Var4 = if_else(row == 1, 500, Var1 - Var3),
           Var5 = 0.1)
}

Output

> df
  row Var1  Var2   Var3   Var4 Var5
1   1  500  0.00   0.00 500.00  0.1
2   2  500 50.00  50.00 450.00  0.1
3   3  500 45.00  95.00 405.00  0.1
4   4  500 40.50 135.50 364.50  0.1
5   5  500 36.45 171.95 328.05  0.1
Jon Spring
  • 55,165
  • 4
  • 35
  • 53
1

A base R solution.

We pre-allocate df with the starting values

df <- data.frame(
    Var1 = rep(500, 5),
    Var2 = 0,
    Var3 = 0,
    Var4 = 500,
    Var5 = rep(0.1, 5)
)

We note that that we can re-write the recursive relationships as

Var4[i] = Var1[i] - Var4[i-1] * Var5[i] - Var3[i-1]
Var3[i] = Var4[i-1] * Var5[i] + Var3[i-1]
Var2[i] = Var4[i-1] * Var5[i]

We can then replace values in df within one for loop

for (i in 2:nrow(df)) {
    df$Var4[i] = df$Var1[i] - df$Var4[i-1] * df$Var5[i] - df$Var3[i-1]
    df$Var3[i] = df$Var4[i-1] * df$Var5[i] + df$Var3[i-1]
    df$Var2[i] = df$Var4[i-1] * df$Var5[i]
}
df
#  Var1  Var2   Var3   Var4 Var5
#1  500  0.00   0.00 500.00  0.1
#2  500 50.00  50.00 450.00  0.1
#3  500 45.00  95.00 405.00  0.1
#4  500 40.50 135.50 364.50  0.1
#5  500 36.45 171.95 328.05  0.1
Maurits Evers
  • 49,617
  • 4
  • 47
  • 68