关于数据变更余额的复利计算

时间:2014-01-24 15:08:05

标签: r data.table

我有一个data.table,它有一个平衡点。余额基于每个期间的存款/取款。每个期间都有一个应该适用的利率。但是,我无法将利率与余额相结合,基本上将利率应用于余额,然后使用下一期间的更新余额来计算新值。

Balance_t1 = (0 + Deposit_t1)*(1+Interest_t1)

Balance_t2 = (Balance_t1 + Deposit_t2)*(1+Interest_t2)

Balance_t3 = (Balance_t2 + Deposit_t3)*(1+Interest_t3)

我有以下data.table

dtCash <- data.table(
  Deposit = c(100, 100, -300, 0), 
  Balance = c(100, 200, -100, -100),
  Interest=c(0.1, 0.01, 0.2, 0.1)
)

结果将是:

dtCash <- data.table(
  Deposit = c(100, 100, -300, 0), 
  Balance = c(100, 200, -100, -100), 
  Interest=c(0.1, 0.01, 0.2, 0.1), 
  BalanceWithInterest = c(110, 212.1, -105.48, -116.028)
)

如何在每个时段更新和引用更新的余额列?

4 个答案:

答案 0 :(得分:3)

您似乎正在寻找累积金额和产品,&#34;我不知道R中的一种方法(例如,@ dynamo&#39; s for循环)。

话虽这么说,这可以通过一个相对简单的Rcpp解决方案有效地完成:

library(Rcpp)
getBalance <- cppFunction(
  "NumericVector getBalance(NumericVector deposit,
                            NumericVector interest) {
    NumericVector result(deposit.size());
    double prevResult = 0.0;
    for (int i=0; i < deposit.size(); ++i) {
      result[i] = (prevResult + deposit[i]) * (1.0 + interest[i]);
      prevResult = result[i];
    }
    return result;
  }")
Deposit <- c(100, 100, -300, 0)  
Interest <- c(0.1, 0.01, 0.2, 0.1)
getBalance(Deposit, Interest)
# [1]  110.000  212.100 -105.480 -116.028

了解Rcpp与基础R的效率改进:

# Base R solution
f2 = function(Deposit, Interest) {
  Balance <- c(0, rep(NA, length(Deposit)))
  for (i in 2:length(Balance)) {
    Balance[i] = (Balance[i-1] + Deposit[i-1]) * (1+Interest[i-1])
  }
  return(Balance[-1])
}

set.seed(144)
Deposit <- runif(1000000, -1, 2)
Interest = runif(1000000, 0, 0.05)
system.time(getBalance(Deposit, Interest))
#    user  system elapsed 
#   0.008   0.000   0.008 
system.time(f2(Deposit, Interest))
#    user  system elapsed 
#   4.701   0.008   4.730 

答案 1 :(得分:1)

还没有足够的回复评论:

您能否说明您希望更新时每个点/哪些数据?您是否希望根据利息,余额(t-1)和存款(t)计算balance_after_interest(t)?

答案 2 :(得分:1)

有点凌乱的答案:

library(data.table)

dtCash <- data.table(
  Deposit = c(100, 100, -300, 0), 
  Balance = c(100, 200, -100, -100),
  Interest=c(0.1, 0.01, 0.2, 0.1)
)
# Add row for t = 0
dtCash <- rbind(rep(0, ncol(dtCash)), dtCash)
# Add "dummy" column for interest-accrued balance
dtCash$Balance.1 <- c(0, rep(NA, nrow(dtCash)-1))

for ( i in seq(nrow(dtCash))[-1] ) {
    dtCash$Balance.1[i] <- (dtCash$Balance.1[i - 1] + dtCash$Deposit[i]) *
                              (1 + dtCash$Interest[i])
}

dtCash
#    Deposit Balance Interest Balance.1
# 1:       0       0     0.00     0.000
# 2:     100     100     0.10   110.000
# 3:     100     200     0.01   212.100
# 4:    -300    -100     0.20  -105.480
# 5:       0    -100     0.10  -116.028
这是什么意思?这不是超级高效的,但它确实可以满足您的需求。通过一些巧妙的重新参数化,您可能会在显式循环中工作。

此外,如果您的问题规模很小,您也可以使用data.frame而不是data.table。在这种情况下,符号将是相同的。 (在这种情况下,使用data.table没有任何好处。)

答案 3 :(得分:1)

我认为您需要提取数据,使用lapply()进行处理并更新它。我认为没有任何矢量方法可以做到这一点:

interest<-dtCash[,Interest]
balance<-dtCash[,Balance]
lapply(1:(length(interest)-1), # leave the last entry - nothing to add it to
       function(x)
         {balance[x+1]<<-balance[x+1]+balance[x]*interest[x]} # remember the double arrow
       )                                                      # because you're in a function

dtCash[,rollBal:=balance]

Deposit Balance Interest rollBal
1:     100     100     0.10  100.00
2:     100     200     0.01  220.00
3:    -300    -100     0.20  -95.70
4:       0    -100     0.10 -138.72