Reduce()在R中贷款建模中的应用

Reduce()在R中贷款建模中的应用,r,data.table,reduce,R,Data.table,Reduce,我正在模拟贷款余额,并成功获得恒定利率: library(data.table) nT <- 5 int <- 1.1 loan <- data.table(loan.age = seq(0:(nT-1)), payment = c(5000, -rep(1000,(nT-1)))) f <- function(balance, payment) payment + int * balance loan[, c("interest", "balance") := 0

我正在模拟贷款余额,并成功获得恒定利率:

library(data.table)
nT <- 5
int <- 1.1

loan <- data.table(loan.age = seq(0:(nT-1)), payment = c(5000, -rep(1000,(nT-1))))

f <- function(balance, payment) payment + int * balance

loan[, c("interest", "balance") := 0
     ][,balance := Reduce(f, payment, accumulate = TRUE) 
     ][,interest := c(0, diff(balance) - payment[-1]) 
     ]
但是,我需要为每个期间申请不同的利息,例如:

int <- rnorm(nT, mean = 0.1, sd = 0.02) + 1
我被绊倒了,有人能帮我修一下吗


提前感谢。

如果在函数
f
中引入调试器,您将看到发生了什么:

f
平衡
# [1] 5000
#浏览[2]>
付款
# [1] -1000
#浏览[2]>
int
# [1] 1.127515 1.131305 1.149106 1.118575 1.087982
#浏览[2]>
付款+整数*余额
# [1] 4637.577 4656.526 4745.531 4592.875 4439.911
###继续,让它做自己的事情
贷款
#贷款期限付款利息余额
# 1:        1    5000        0                                         5000
# 2:        2   -1000        0 4637.577,4656.526,4745.531,4592.875,4439.911
# 3:        3   -1000        0 4228.940,4267.952,4453.119,4137.476,3830.544
# 4:        4   -1000        0 3768.195,3828.356,4117.106,3628.077,3167.563
# 5:        5   -1000        0 3248.698,3331.039,3730.992,3058.277,2446.252
贷款余额[2]
# [[1]]
# [1] 4637.577 4656.526 4745.531 4592.875 4439.911
我认为您的意思是对表的每一行使用每个
int
。不幸的是,这不是
Reduce
的自然现象,因此我们必须稍微调整一下。我将把
payment
int
向量与
Map(list,payment,int)
一起“压缩”,这需要一些清理

set.seed(2)
int
平衡
# [[1]]
# [1] 5000
# [[2]]
# [1] 1.082062
#浏览[2]>
付款[[1]]+付款[[2]]*余额[[1]]
# [1] 4518.485
#浏览[2]>
###继续进行直到完成
贷款
#贷款期限付款利息余额
# 1:        1    5000        0   
# 2:        2   -1000        0 4518.485
# 3:        3   -1000        0 4113.827
# 4:        4   -1000        0 3432.206
# 5:        5   -1000        0 2769.918
贷款余额[[1]]
# [[1]]
# [1] 5000
# [[2]]
# [1] 1.082062
显然,我们不能将
余额
作为列表列。。。因此,我们可以提取并使用另一条管线取消列出它:


f3一个选项是
contracted2
from
purrr

library(purrr)
library(dplyr)
loan %>%
   mutate(balance = flatten_dbl(accumulate2(payment, int,  ~ 
             ..2 + ..3 * ..1  , .init = 0)[-1]),        
          interest = c(0, diff(balance) - payment[-1]))
#   loan.age payment  balance interest
#1        1    5000 5000.000   0.0000
#2        2   -1000 4518.485 518.4849
#3        3   -1000 4113.827 595.3416
#4        4   -1000 3432.206 318.3793
#5        5   -1000 2769.918 337.7118
数据
nT
lag
应该是一列吗?它可能会拾取
lag
函数,如果您试图从一个数字中减去它,它会抛出该错误。他将每个
付款
乘以
int
的整个向量,这将生成一个长度为5的列表列(大多数情况下)。(现在正在修复…)这可能有点过分,但因为我以前见过类似的需求(在这里和我的日常工作中),我编写了一个函数,它将
Reduce
简化论与
Map
的k元参数处理相结合。这里是:,并在示例部分包括对该问题答案的改编
我必须强调,my几乎是
Reduce
到k元参数的直译。我不知道代码布局是否能更好,我只花了很小的努力,实现了k元逻辑的文字集成。亲爱的@r2evans,谢谢你的解决方案,我需要学习很多,你的逐步解释帮助我消化了所有这些信息。我还查看了MapReduce(),它工作得非常好。但我会坚持你提出的非常快速的解决方案,我会反复使用它,所以速度是我的一个关键点。谢谢,我试过了,效果很好。你好,法比奥。
Error in r[i1] - r[-length(r):-(length(r) - lag + 1L)] : 
non-numeric argument to binary operator
library(purrr)
library(dplyr)
loan %>%
   mutate(balance = flatten_dbl(accumulate2(payment, int,  ~ 
             ..2 + ..3 * ..1  , .init = 0)[-1]),        
          interest = c(0, diff(balance) - payment[-1]))
#   loan.age payment  balance interest
#1        1    5000 5000.000   0.0000
#2        2   -1000 4518.485 518.4849
#3        3   -1000 4113.827 595.3416
#4        4   -1000 3432.206 318.3793
#5        5   -1000 2769.918 337.7118
nT <- 5
set.seed(2)
int <- rnorm(nT, mean = 0.1, sd = 0.02) + 1
loan <- data.table(loan.age = seq(0:(nT-1)), payment = c(5000, -rep(1000,(nT-1))))