使用tidyverse生态的purrr实现数据框递归计算求助
解决tibble中迭代计算capital的问题
原代码的问题在于错误地将全为NA的capital列作为accumulate2的输入,且函数参数使用不符合语法。以下是两种正确实现方式:
方法1:使用purrr::accumulate
因为我们只需要遍历yield序列进行迭代计算,accumulate更简洁:
library(tidyverse) tribble( ~year, ~yield, ~capital, ~expected, 1, 1.02, NA, 45900, 2, 0.89, NA, 36401, 3, 1.1, NA, 34541.1, 4, .92, NA, 27177.81, ) %>% mutate(capital = accumulate(yield, ~ (.x - 5000) * .y, .init = 50000) %>% tail(-1))
解释:
accumulate以初始值50000开始,依次将前一次的计算结果与当前yield代入公式(上一期capital - 5000) * 当前yieldtail(-1)是因为accumulate会返回包含初始值的结果(共5个值),去掉第一个初始值后正好匹配数据框的4行
方法2:使用purrr::accumulate2
如果一定要用accumulate2,需要构造与yield等长的withdrawal序列,函数参数需对应累积值、withdrawal、yield三个输入:
library(tidyverse) tribble( ~year, ~yield, ~capital, ~expected, 1, 1.02, NA, 45900, 2, 0.89, NA, 36401, 3, 1.1, NA, 34541.1, 4, .92, NA, 27177.81, ) %>% mutate(capital = accumulate2(rep(5000, n()), yield, ~ (.x - .y) * .z, .init = 50000) %>% tail(-1))
验证结果
两种方法计算出的capital列都会与expected列完全匹配:
- 第1年:
(50000-5000)*1.02 = 45900 - 第2年:
(45900-5000)*0.89 = 36401 - 第3年:
(36401-5000)*1.1 = 34541.1 - 第4年:
(34541.1-5000)*0.92 = 27177.81
内容的提问来源于stack exchange,提问作者jens_laufer
相关产品推荐
相关产品推荐

