Search code examples
riterationsubtraction

Within column subtraction iteratively in R


I have the following data:

library tidyverse

age_grp <- c(10,9,8,7,6,5,4,3,2,1)
start <- c(0.420,0.420,0.420,0.420,0.420,0.420,0.420,0.420,0.420,0.420)
change <- c(0.020,0.033,0.029,0.031,0.027,0.032,0.032,0.030,0.027,0.034)
final_outcome <- c(0.400,0.367,0.338,0.307,0.28,0.248,0.216,0.186,0.159,0.125)
my_data <- data.frame(age_grp,start,change,final_outcome)

my_data1 <- my_data %>% 
  dplyr::arrange(age_grp)

I would like to subtract the values in the variable change from the values in the variable start such that it is an iterative decrease from the oldest age group to the youngest. The final values that I am looking to get are in the variable final_outcome. For example, starting with age_grp 10, I want to subtract 0.20 from 0.420 to get 0.400. Then, I would like to subtract 0.033 from 0.400 to get 0.367 and so forth. I am struggling with how to store those differences. I have made an attempt below, but I don't know how to store the difference to then continue the subtraction forward (or backward, depending on how you look at it). Any advice or suggestions would be appreciated.

my_data1$attempt <- NA

#calculating the decreases
for(i in 2:nrow(my_data1)) 
   my_data1$attempt[i] <- round(my_data1$start[i] - my_data1$change[i-1], 4)

Solution

  • If we need the same output as in final_outcome

    library(dplyr)
    my_data %>% 
       mutate(attempt = start - cumsum(change)) %>%
       arrange(age_grp)
    

    -output

    #  age_grp start change final_outcome attempt
    #1        1  0.42  0.034         0.125   0.125
    #2        2  0.42  0.027         0.159   0.159
    #3        3  0.42  0.030         0.186   0.186
    #4        4  0.42  0.032         0.216   0.216
    #5        5  0.42  0.032         0.248   0.248
    #6        6  0.42  0.027         0.280   0.280
    #7        7  0.42  0.031         0.307   0.307
    #8        8  0.42  0.029         0.338   0.338
    #9        9  0.42  0.033         0.367   0.367
    #10      10  0.42  0.020         0.400   0.400