在 R 中迭代地进行列减法

Within column subtraction iteratively in R

我有以下数据:

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)

我想从变量 start 中的值中减去变量 change 中的值,这样它就是从最年长的年龄组到最年轻的年龄组的迭代递减。我希望获得的最终值在变量 final_outcome 中。例如,从 age_grp 10 开始,我想用 0.420 减去 0.20 得到 0.400。然后,我想从 0.400 中减去 0.033 得到 0.367 等等。我正在为如何存储这些差异而苦苦挣扎。我在下面进行了尝试,但我不知道如何存储差异然后继续向前减法(或向后减,取决于你如何看待它)。如有任何意见或建议,我们将不胜感激。

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)
library(tidyverse)
my_data %>% 
  mutate(attempt = accumulate(change, ~ .x - .y, .init = start[1])[-1])

注意:accumulate 来自属于 tidyversepurrr 库。它还有一个 .dir 参数,您可以在其中转到 "forward""backward".

或在基础 R 中使用 Reduce:

within(my_data, attempt <- Reduce("-", change, init = start[1], accumulate = T)[-1])

Reduce 有一个参数 right 也可以向前或向后计算。

输出

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

如果我们需要与final_outcome

相同的输出
library(dplyr)
my_data %>% 
   mutate(attempt = start - cumsum(change)) %>%
   arrange(age_grp)

-输出

#  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
my_data$final <- my_data$start - cumsum(my_data$change)