2

考虑以下向量x

 > 1:9
 [1] 1 2 3 4 5 6 7 8 9

并考虑以下输入:

 start = 10
 pmt = 2

res这是我想要实现的结果(我们称之为结果向量)(显示的是实际公式)。请注意,结果是向量而不是数据框。我只是在这里显示了 2 个维度。

在此处输入图像描述

换句话说,要获得res,您需要start乘以每个单元格的累积乘积,df直到对应的单元格。

当向量索引为 4 或 7 的倍数时,更新起始值。

这是我尝试过的:

     for(i in 1:9) {
         res[i] = start * cumprod(df[k:i])[i]
         if(i %% 3 == 0) {
             start = res[i] - pmt
             k = k + 3
         } else {
             start = res[i]
         }
     }
 }

把这个问题放在上下文中,假设你有 10 美元的初始价值,你想在 9 个月内投资它。但是,您想在每 3 个月末提款(即在第 4 个月、第 7 个月的月初,...)。向量x代表回报的随机值。因此,在第 4 个月的开始,您的起始值start*1*2*3 减去提款pmt

这里的目的是计算第 9 个月末的财富值。

问题是,实际上 i = 200(200 个月),我需要为 10,000 个不同的向量x重做这个计算。因此,在上述代码上循环 10,000 次需要永远执行!

您对如何更有效地计算这个有什么建议吗?我希望解释不会太混乱!

谢谢!

4

2 回答 2

3

如果您将公式计算为res迭代公式,那么编写一个可以提供给的函数会更容易Reduce。这是一个简单的循环

x <- 1:9
start <- 10
pmt <- 2

res <- numeric(length(x))
res[1] <- x[1] * start
for (i in seq_along(x)[-1]) {
  res[i] <- (res[i-1] - (pmt * (!(i%%4) || !(i%%7)))) * x[i]
}

如果你想把它写成一个Reduce函数,它看起来像这样

Reduce(function(r, i) {
  (r - (pmt * (!(i%%4) || !(i%%7)))) * x[i]
}, 
       seq_along(x),
       init = start, 
       accumulate = TRUE)[-1]

由于处理初始值的方式(并且迭代是针对索引而不是值,因为必须在索引上进行比较),因此起始值和删除结果的第一个元素有些奇怪。这里的循环可能更容易理解。

于 2013-10-17T19:55:26.563 回答
0

我知道你提到它是 1d,但我认为这很好用,你可以很容易地将它转换为 1d -

start = 10
pmt = 2

library(data.table)

dt <- data.table(
month = 1:13
)

dt[,principalgrown := start*cumprod(month)]

#explained below#######
dt[,interestlost := 0]
for(i in seq(from = 4, to = (dim(dt)[1]), by = 3))
{
dt[month >= i,interestlost := interestlost + (prod(i:month)), by = month]
}
#######################

dt[,finalamount := principalgrown - (pmt*interestlost)]

#s 中的部分是诀窍。在您计算第 7 个月的值时((1*2*3*start - pmt)*4*5*6 - pmt) * 7,我将其计算为1*2*3*4*5*6*7*start - 4*5*6*7*pmt - 7*pmt1*2*3*4*5*6*7*startprincipalgrown- 4*5*6*7*pmt - 7*pmt-(pmt*interestlost)

于 2013-10-17T20:18:44.720 回答