折现未来现金流量

时间:2019-02-04 11:06:03

标签: r dplyr

我在使用R的dplyr软件包折现特定状态下的帐户现金流时遇到了一些麻烦。

在我的示例中,我们假设一个帐户的数据集如下:

+--------+--------+-------+-----------+--+
| PERIOD | STAGE  | RATE  | CASH FLOW |  |
+--------+--------+-------+-----------+--+
|      1 | Open   | 10%   |       100 |  |
|      2 | Open   | 10.5% |       120 |  |
|      3 | Open   | 10%   |        50 |  |
|      4 | Open   | 11%   |        40 |  |
|      5 | Closed | 10%   |         0 |  |
|      6 | Closed | 11%   |         0 |  |
|      7 | Open   | 11%   |        30 |  |
|      8 | Open   | 10%   |        40 |  |
|      9 | Open   | 10.2% |        50 |  |
+--------+--------+-------+-----------+--+

在1-4和7-9期间,该帐户处于“打开”阶段。

我想在每个观察日使用适用于特定期间的汇率,使用R中的dplyr包计算折现的未来现金流量。

所需结果如下:


| PERIOD | STAGE  | RATE  | CASH FLOW | PV of Cash Flows  |
|--------|--------|-------|-----------|-------------------|
|      1 | Open   | 10%   |       100 | 279.3797 (1)      |
|      2 | Open   | 10.5% |       120 | 198.5124 (2)      |
|      3 | Open   | 10%   |        50 | 86.036 (3)        |
|      4 | Open   | 11%   |        40 | 40                |
|      5 | Closed | 10%   |         0 | NA                |
|      6 | Closed | 11%   |         0 | NA                |
|      7 | Open   | 11%   |        30 | 107.6109 (4)      |
|      8 | Open   | 10%   |        40 | 85,37205 (5)      |
|      9 | Open   | 10.2% |        50 | 50                |

位置:

(1)= 100 + 120 /(1.105)+ 50 /{(1.1)(1.105)} + 40 / {(1.11)(1.1)(1.105)}

(2)= 120 + 50 /(1.1)+ 40 / {(1.11)(1.1)}

(3)= 50 + 40 /(1.11)

(4)= 30 + 40 /(1.1)+ 50 / {(1.102)(1.1)}

(5)= 40 + 50 /(1.102)

是否可以使用dplyr语法获得所需的结果?

与该问题有关的一些其他问题:

  • 代码解决方案必须是通用的,即不同的帐户可能具有不同的结构
  • 我正在使用的数据集相对较大(因此),我想避免出现循环(如果可能)。
  • 如说明性示例所示,每个“开放”阶段都独立于下一阶段。换句话说,在期间1-4的第一个“开放”阶段将不考虑期间7-9的现金流量。

我将不胜感激任何建议/示例代码。

谢谢!


更新:

数据结构:

structure(list(Period = 1:9, Stage = structure(c(2L, 2L, 2L, 
2L, 1L, 1L, 2L, 2L, 2L), .Label = c("Close", "Open"), class = "factor"), 
    Rate = c(0.1, 0.105, 0.1, 0.11, 0.1, 0.11, 0.11, 0.1, 0.102
    ), Cash_flow = c(100, 120, 50, 40, 0, 0, 30, 40, 50)), class = "data.frame", row.names = c(NA, 
-9L))

1 个答案:

答案 0 :(得分:0)

这是将dplyr与少量data.table混合使用的解决方案:

library(dplyr)
data %>% 
  arrange(-Period) %>%
  group_by(stage_nr = data.table::rleid(Stage)) %>% 
  mutate(pv_cf = Cash_flow + cumsum(lag(Cash_flow, default = 0) / (1 + lag(Rate, default = 0)))) %>%
  arrange(Period)

  Period Stage  Rate Cash_flow PV_cf stage_nr pv_cf
   <int> <fct> <dbl>     <dbl> <dbl>    <int> <dbl>
1      1 Open  0.1         100 290.         3 290. 
2      2 Open  0.105       120 201.         3 201. 
3      3 Open  0.1          50  86.0        3  86.0
4      4 Open  0.11         40  40          3  40  
5      5 Close 0.1           0   0          2   0  
6      6 Close 0.11          0   0          2   0  
7      7 Open  0.11         30 112.         1 112. 
8      8 Open  0.1          40  85.4        1  85.4
9      9 Open  0.102        50  50          1  50