R中的滚动计算

R中的滚动计算,r,data.table,R,Data.table,我正在尝试使用数据表在R中建模摊销贷款账户。每行代表一个月。每个月都有一笔还款或预付款,并根据上个月的余额收取利息 例如: > loan <- data.table(loan.age = seq(0:9), payment = c(5000, -rep(100,9))) 这就是我想要的结果: > loan loan.age payment interest balance 1: 0 5000 0.00 5000.00 2:

我正在尝试使用数据表在R中建模摊销贷款账户。每行代表一个月。每个月都有一笔还款或预付款,并根据上个月的余额收取利息

例如:

> loan <- data.table(loan.age = seq(0:9), payment = c(5000, -rep(100,9)))
这就是我想要的结果:

> loan
    loan.age payment interest balance
 1:        0    5000     0.00 5000.00
 2:        1    -100    50.00 4950.00
 3:        2    -100    49.50 4899.50
 4:        3    -100    48.99 4848.49
 5:        4    -100    48.49 4796.98
 6:        5    -100    47.97 4744.95
 7:        6    -100    47.45 4692.40
 8:        7    -100    46.92 4639.32
 9:        8    -100    46.39 4585.71
10:        9    -100    45.87 4531.58
我可以用for循环来解决这个问题,但是在一个大的投资组合中,它的速度是不可行的。在上下文中,使用年金公式的300个月贷款比For循环快100倍(每笔贷款2秒,而不是20毫秒)

我已经尝试将表连接到它本身,我也尝试了数据表1.9.5中新增的shift()函数,但我无法找到一种方法来强制从上到下执行计算,从而使新的平衡沿着表波动

我的代码目前使用从年金公式推导出的一些金融数学来计算每个时期的余额,但如果利率在贷款过程中发生部分变化,这种方法将不起作用

谢谢

编辑:我认为这个问题已经解决了。解决方案2b)来自 G.下面的Grothendieck给出了一个通用的解决方案,它既适用于这个简单的情况,也可以扩展到更复杂的情况。

1)试试
过滤器

loan[, c("interest", "balance") := 0][, 
     balance := c(filter(payment, 1.01, method = "recursive"))][,
     interest := c(0, diff(balance) - payment[-1])]
给予:

> loan
    loan.age payment interest  balance
 1:        1    5000  0.00000 5000.000
 2:        2    -100 50.00000 4950.000
 3:        3    -100 49.50000 4899.500
 4:        4    -100 48.99500 4848.495
 5:        5    -100 48.48495 4796.980
 6:        6    -100 47.96980 4744.950
 7:        7    -100 47.44950 4692.399
 8:        8    -100 46.92399 4639.323
 9:        9    -100 46.39323 4585.716
10:       10    -100 45.85716 4531.574
注意:最后一行可以交替写入:

         interest := .01 * c(0, balance[-.N])]
或在data.table的开发版本中:

         interest := .01 * shift(balance, fill = 0)[[1]]]
2)减少另一种可能性是:

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

loan[, c("interest", "balance") := 0][, 
     balance := Reduce(f, payment, accumulate = TRUE) ][,
     interest := c(0, diff(balance) - payment[-1]) ]
2b)这允许
付款
费率
发生变化:

loan$rate <- .01
h <- function(balance, i) loan$payment[i] + (1 + loan$rate[i]) * balance

loan[, c("interest", "balance") := 0][, 
     balance := Reduce(h, .I[-1], init = payment[1], accumulate = TRUE) ][,
     interest := c(0, diff(balance) - payment[-1]) ]

贷款美元利率关于
利息
列,你有公式吗?“利息应该是上个月余额的0.01倍,余额应该是上个月的余额加上本月的利息。”-你的例子中不是这样的。请修复它。很抱歉造成混淆-工作示例是正确的,但我的叙述不完整。我已经更正了描述并添加了一行伪代码来显示数学是如何工作的。什么是:=运算符?它是data.table的一部分。从R,
库(data.table);help(“:=”
对于我描述的简单案例非常有效。但是,我还想为利率添加一列,以允许利率在贷款的整个生命周期内发生变化。我看不出有任何方法可以通过过滤器实现这一点-使用向量作为第二个参数不会将向量的每个元素应用于贷款的每个元素。我们添加了第二种方法。哇!除了第一个示例中的一个轻微的输入错误(额外的}符号),这是绝对完美的。特别是2b)给出了一个清晰、表达力强、通用的解决方案,我可以用它来计算贷款的各种其他滚动统计数据。我还没有测试它的性能,但这是一个工具,我肯定会在各种情况下使用。非常感谢你。
loan$rate <- .01
g <- function(balance, rate) loan$payment[2] + (1 + rate) * balance

loan[, c("interest", "balance") := 0][, 
     balance := Reduce(g, rate[-1], init = payment[1], accumulate = TRUE) ][,
     interest := c(0, diff(balance) - payment[-1]) ]
loan$rate <- .01
h <- function(balance, i) loan$payment[i] + (1 + loan$rate[i]) * balance

loan[, c("interest", "balance") := 0][, 
     balance := Reduce(h, .I[-1], init = payment[1], accumulate = TRUE) ][,
     interest := c(0, diff(balance) - payment[-1]) ]