Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dplyr: Iterative calculation

I'm trying to figure out if there's a way for dplyr to calculate a variable row-by-row, such that it can reference the results calculated one record prior.

Here is code that achieves what I want using for-loops:

x <- data.frame(x1 = c(1:10)) 

#This works.
x$x2[1] <- 0

for (i in 2:nrow(x)) {
  x$x2[i] <- x$x2[i-1]*1.1 + 1
}

My naive dplyr attempt, which doesn't work:

#This doesn't work. "Error: object'x1' not found"
x %>% mutate(x2 = ifelse(x1 == 1, 0, lag(x2)*1.1 + 1))

It would be nice to find a dplyr solution since this step is part of a workflow that heavily relies on it.

Thank you.


Edit:

The above is a simplified example of what I'm trying to do. A closed form solution will not work because the function applied is more complex and dynamic than what is shown here. For example, suppose that 'add_var' and 'pwr_var' are random integers, and I want to calculate this:

x$x2[1] <- 0

for (i in 2:nrow(x)) {
  x$x2[i] <- ( x$x2[i-1]*1.1 + x$add_var[i] ) ^ x$pwr_var[i]
}
like image 936
Ber Avatar asked Jul 05 '26 19:07

Ber


1 Answers

In general, if you want to calculate values that rely on previous values, you are better off using Reduce. here's an example with your data

x %>% mutate(x3 = Reduce(function(a,b) a*1.1+1, 1:(n()-1), 0, acc=T))

But in your example, there is a closed form for the term that doesn't rely on iteration. You can do

x %>% mutate(x4=(1.1^(row_number()-1)-1)/(1.1-1)*1)
like image 155
MrFlick Avatar answered Jul 08 '26 12:07

MrFlick



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!