我有一个大数据集(大约 20 万行),其中每一行都是一笔贷款。我有贷款金额,付款次数和贷款付款。
我正在尝试获得贷款利率。
R 没有计算这个的函数(至少基本 R 没有它,我找不到它)。
编写 npv 和 irr 函数并不难

Npv <- function(i, cf, t=seq(from=0,by=1,along.with=cf)) sum(cf/(1+i)^t)
Irr <- function(cf) { uniroot(npv, c(0,100000), cf=cf)$root }

你可以做
rate = Irr(c(amt,rep(pmt,times=n)))

问题是当您尝试计算大量付款的费率时。因为 uniroot 不是矢量化的,并且因为 rep 花费了惊人的时间,所以最终计算速度很慢。如果您进行一些数学运算并弄清楚您正在寻找以下等式的根,则可以使其更快
zerome <- function(r) amt/pmt-(1-1/(1+r)^n)/r

然后将其用作 uniroot 的输入。在我的电脑中,这需要大约 20 秒才能为我的 200k 数据库运行。

问题是我正在尝试做一些优化,这是优化的一个步骤,所以我试图进一步加快速度。

我已经尝试过矢量化,但因为 uniroot 没有被矢量化,所以我不能更进一步。是否有任何矢量化的寻根方法?

谢谢

最佳答案

您可以使用线性插值器,而不是使用根查找器。您必须为 n 的每个值(剩余付款次数)创建一个插值器。每个插值器将 (1-1/(1+r)^n)/r 映射到 r 。当然,您必须构建足够精细的网格,以便将 r 返回到可接受的精度级别。这种方法的好处是线性插值器速度快且矢量化:您可以在对相应插值器的一次调用中找到具有相同剩余还款数 (n) 的所有贷款的利率。

现在一些代码证明它是一个可行的解决方案:

首先,我们创建内插器,每个可能的 n 值一个:

n.max <- 360L  # 30 years

one.interpolator <- function(n) {
    r <- seq(from = 0.0001, to = 0.1500, by = 0.0001)
    y <- (1-1/(1+r)^n)/r
    approxfun(y, r)
}

interpolators <- lapply(seq_len(n.max), one.interpolator)

请注意,我使用了 1/100 百分比 (1bp) 的精度。

然后我们创建一些假数据:
n.loans <- 200000L
n     <- sample(n.max, n.loans, replace = TRUE)
amt   <- 1000 * sample(100:500, n.loans, replace = TRUE)
pmt   <- amt / (n * (1 - runif(n.loans)))
loans <- data.frame(n, amt, pmt)

最后,我们解决 r :
library(plyr)
system.time(ddply(loans, "n", transform, r = interpolators[[n[1]]](amt / pmt)))
#    user  system elapsed
#   2.684   0.423   3.084

它很快。请注意,一些输出率是 NA 但这是因为我的随机输入没有意义,并且会返回我选择的 [0 ~ 15%] 网格之外的率。你的真实数据不会有这个问题。

关于r - 大量贷款的快速贷款利率计算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13868990/

10-12 18:00