r语言 - 计算所有时间点现金流的 NPV



>我有以下数据框包含多个项目的现金流。例如:

test <- data.frame(ID = c(rep("A",3), rep("B",4)), 
        time = c("y3","y2","y1","y4","y3","y2","y1"),
        Cfs= c(rep(1,3),rep(2,4)),
        interest = c(rep(0.1,3),rep(0.05,4)))
ID  time    CFs interest
A   y3      1   0.1
A   y2      1   0.1
A   y1      1   0.1
B   y4      2   0.05
B   y3      2   0.05
B   y2      2   0.05
B   y1      2   0.05

我想为每个项目生成每个时间点的净现值,因此最终输出应如下所示:

ID  time   CFs  interest    NPV
A   y3     1    0.1         2.487
A   y2     1    0.1         1.736
A   y1     1    0.1         0.909
B   y4     2    0.05        7.092
B   y3     2    0.05        5.446
B   y2     2    0.05        3.719
B   y1     2    0.05        1.905

通过阅读一些旧帖子,我能够计算出每个项目的总现金流的净现值,但我不确定在每个时间段如何做到这一点。另外,由于实际数据集非常大(300k+(,我也试图避免循环。

谢谢

您可能会发现其中一些帮助程序函数很有用

dcf <- function(x, r, t0=FALSE){
  # calculates discounted cash flows (DCF) given cash flow and discount rate
  #
  # x - cash flows vector
  # r - vector or discount rates, in decimals. Single values will be recycled
  # t0 - cash flow starts in year 0, default is FALSE, i.e. discount rate in first period is zero.
  if(length(r)==1){
    r <- rep(r, length(x))
    if(t0==TRUE){r[1]<-0}
  }
  x/cumprod(1+r)
}
npv <- function(x, r, t0=FALSE){
  # calculates net present value (NPV) given cash flow and discount rate
  #
  # x - cash flows vector
  # r - discount rate, in decimals
  # t0 - cash flow starts in year 0, default is FALSE
  sum(dcf(x, r, t0))
}

现在,我们可以应用dplyr的力量

library(dplyr)
test %>% mutate_if(is.factor, as.character) %>% 
  arrange(ID, time) %>% 
  group_by(ID) %>% 
  mutate(DCF=cumsum(dcf(x=Cfs, r=interest)))
#> # A tibble: 7 x 5
#> # Groups:   ID [2]
#>      ID  time   Cfs interest       DCF
#>   <chr> <chr> <dbl>    <dbl>     <dbl>
#> 1     A    y1     1     0.10 0.9090909
#> 2     A    y2     1     0.10 1.7355372
#> 3     A    y3     1     0.10 2.4868520
#> 4     B    y1     2     0.05 1.9047619
#> 5     B    y2     2     0.05 3.7188209
#> 6     B    y3     2     0.05 5.4464961
#> 7     B    y4     2     0.05 7.0919010

这个问题很旧,但我在这里写下我的答案,也许对某人有帮助:

您需要在for()循环中使用cumsum()cumprod()计算每个 ID 的 NPV,如下所示:

test <- test %>% mutate(npv = -1)
for(j in unique(test$ID)){
  x <- (test %>% filter(ID == j))$Cfs
  irr <- (test %>% filter(ID == j))$interest
  npv <- cumsum(x/cumprod(1+irr)) %>% round(3)
  test$npv[test$ID==j] <- npv[length(npv):1]
}
test

结果如下:

  ID time Cfs interest   npv
1  A   y3   1     0.10 2.487
2  A   y2   1     0.10 1.736
3  A   y1   1     0.10 0.909
4  B   y4   2     0.05 7.092
5  B   y3   2     0.05 5.446
6  B   y2   2     0.05 3.719
7  B   y1   2     0.05 1.905

最新更新