1

I'm trying to reference the value in a previous calculation during the current one. I've tried using shift(), but it does not work when using the same variable.

 x  
 1  
 2  
 3  
 5  
 1

I want to do something like this. I want shift(z) to refer to the previously calculated value of the same variable. If I run this, I get an error saying that object 'z' was not found.

dt[, z := 0.1 * x + 0.2 * shift(z)]

How do I do this without writing a loop?

4
  • pipe it: dt[, z := 0.1 * x + 0.2 ][, z:= z * shift(z)] Commented Dec 10, 2018 at 12:48
  • I want it to start with zero for the first one. Then use the value from the previous row. So, (0.1*1 + 0.2*0) would be first row. The second would be (0.1*2 + 0.2*0.1(The value from the first row)). Commented Dec 10, 2018 at 12:50
  • YOLO, doesn't that mess with the order of operations? I want to multiply by the previous value of z before doing the addition. Commented Dec 10, 2018 at 12:57
  • 1
    desired output unclear Commented Dec 10, 2018 at 13:57

1 Answer 1

3

We need a logic with accumulate

library(tidyverse)
dt %>% 
  mutate(z = tail(accumulate(x, ~ .y * 0.1 + 0.2 * .x, .init = 0), -1))
#  x       z
#1 1 0.10000
#2 2 0.22000
#3 3 0.34400
#4 5 0.56880
#5 1 0.21376

Or the same logic with Reduce

dt[, z := tail(Reduce(function(x, y)  y * 0.1 + 0.2 * x, x, 
     init = 0, accumulate = TRUE), -1)]
Sign up to request clarification or add additional context in comments.

5 Comments

while reading your solutions sometimes I feel like I know nothing.
What do the .x and .y parts mean?
@YOLO This one is a bit tricky, but you will get used to it. It is just understanding that recursive logic
@buckbeak Here .x refers to the value that gets updated and .y the actual values. You can check it by dt %>% mutate(z = tail(accumulate(x, ~ .x, .init = 0), -1)) dt %>% mutate(z = tail(accumulate(x, ~ .y, .init = 0), -1))
@buckbeak If you check the ?accumulate the description is # .x is the accumulating value 1:10 %>% accumulate(~ .x) # .y is element in the list

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.