SportSci
SportSci

Reputation: 247

Is there a function or a way to build off previous values in formulas

I am trying to create a new vector by a formula, but I want to include the result of that formula for subsequent values in the same vector. Is there a simple way to do this that I am missing?

I am starting with one value and then multiplying it by a percentage (v1) that changes each year. I can get that to work, but it only includes that row and I would like it to be a running sum. I've tried manually inserting the row 1 value (1000) and then doing a formula for the remaining rows [2:10], but that's not working either (getting NAs) and I don't think that will actually result in what I want. 1000 should be the initial value and each of the following should build off it and the row above. I want each row to start with the previous row's answer and multiply it by the percentage. I've tried this several ways and have searched for the answer, but I think I'm not using the correct terminology or something, as I am sure there is a simpler way to do this. Here's a reproducible example:

    library(dplyr)
    df <- data.frame(Year = c(2010:2019),
             v1 = c(1.05, 1.1, 1.12, 1.15, 1.05, 1.3, 1.2, 1.2, 1.1, 1.1))
    df$v2[1]=1000
    df <- df %>%
      mutate(v2 = v2[2:10] * v1 + v2[1])

The intended result should look like this.

       Year   v1      v2
    1  2010 1.05 1050.00
    2  2011 1.10 1155.00
    3  2012 1.12 1293.60
    4  2013 1.15 1487.64
    5  2014 1.05 1562.02
    6  2015 1.30 2030.63
    7  2016 1.20 2436.75
    8  2017 1.20 2924.11
    9  2018 1.10 3216.52
    10 2019 1.10 3538.17

So v2[1] = 1000*1.05, v2[2] = 1050*1.10, v2[3] = 1155*1.12, etc.

Upvotes: 1

Views: 218

Answers (1)

akrun
akrun

Reputation: 887108

We can use accumulate from purrr

library(tidyverse)
df %>% 
   mutate(v2 = tail(accumulate(v1, ~ .x * .y, .init = 1000), -1))
#   Year   v1       v2
#1  2010 1.05 1050.000
#2  2011 1.10 1155.000
#3  2012 1.12 1293.600
#4  2013 1.15 1487.640
#5  2014 1.05 1562.022
#6  2015 1.30 2030.629
#7  2016 1.20 2436.754
#8  2017 1.20 2924.105
#9  2018 1.10 3216.516
#10 2019 1.10 3538.167

A base R option is

tail(Reduce(function(x, y) x * y, df$v1, init = 1000, accumulate = TRUE), -1)
#[1] 1050.000 1155.000 1293.600 1487.640 1562.022 2030.629 
#[7] 2436.754 2924.105 3216.516 3538.167

Upvotes: 1

Related Questions