Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiply constant by previous row and accumulate result in R

Tags:

r

dplyr

I'm trying to compute a new column in a dataframe that multiply a constant by the value of the previous row (in the new created column B) and accumulate the result.

To clarify, here is an example of my original data:

A  
---
100
200
300
400
500

An here is what I'm trying to accomplish:

A    B
-----------
100  100.00
200  302.00
300  608.04
400  1020.20
500  1540.60

(The constant being in this case: 0.02)

The (approximate) formula that I am using in excel is something similar to this:

=(B1*(1+constant)+A2) [In Cell B2]

I've tried using lag, mutate and cumsum from dplyr to achieve this, but so far I've had no luck. Here a reproducible example of what I've managed to achieve thus far:

rate = .02
A <- c(100,200,300,400,500)

df <- data.frame(A)

df = df %>%
  mutate(B = lag(A,default=0)*(1+rate)) %>% 
  mutate(B = cumsum(B)+df$A) 

This produce the following output (different than what I'm trying to get):

A    B
100  100.00
200  302.00
300  606.00
400  1012.00
500  1520.00

Can anyone help me with some code to compute this? Thanks for the help!

like image 471
neek05 Avatar asked Oct 26 '25 13:10

neek05


2 Answers

We can use accumulate

library(dplyr)
library(purrr)
df %>%
    mutate(B = accumulate(A, ~ .x*(1 + rate) + .y))

-output

  A        B
1 100  100.000
2 200  302.000
3 300  608.040
4 400 1020.201
5 500 1540.605

Or the same option in base R using Reduce

 Reduce(function(.x, .y) .x * (1 + rate)  + .y, df$A, accumulate = TRUE)
[1]  100.000  302.000  608.040 1020.201 1540.605
like image 157
akrun Avatar answered Oct 29 '25 05:10

akrun


Here's a way to do it using a recursive function:

f = function(x) if (x == 1) 100 else 100 * x + (1 + rate) * f(x - 1)
res <- c()
for(i in 1:5) res <- c(res, f(i))

df %>% 
  mutate(B = res)
    A        B
1 100  100.000
2 200  302.000
3 300  608.040
4 400 1020.201
5 500 1540.605
like image 29
Maël Avatar answered Oct 29 '25 03:10

Maël