R语言 计算多个滞后值的乘积

yi0zb3m4  于 2023-03-20  发布在  其他
关注(0)|答案(1)|浏览(131)

我有以下类型的数据框架,其中的日期可能不平衡,并且在RETURN列中可能有一些缺失的数据:
| 日期|代码|退货|
| - ------|- ------|- ------|
| 二零零零年一月一日|资产_1| -0.02 |
| 二零零零年二月一日|资产_1|0.02分|
| 二零零零年三月一日|资产_1|0.01分|
| 二零零零年四月一日|资产_1|0.02分|
| 二零零零年五月一日|资产_1|0.03分|
| 二零零零年六月一日|资产_1| -0.02 |
| 二零零零年七月一日|资产_1|0.05分|
| 二零零零年八月一日|资产_1| -0.04 |
| 二零零零年九月一日|资产_1| -0.02 |
| 二零零零年十月一日|资产_1|无|
| 二○ ○ ○年十一月一日|资产_1|0.05分|
| 二零零零年十二月一日|资产_1|0.03分|
| 二零零零年三月一日|资产_2|不适用|
| 二零零零年四月一日|资产_2| -0.02 |
| 二零零零年五月一日|资产_2|不适用|
| 二零零零年六月一日|资产_2| -0.03 |
| 二零零零年七月一日|资产_2|0.05分|
| 二零零零年八月一日|资产_2|0.02分|
| 二零零零年九月一日|资产_2| -0.03 |
| 二零零零年十月一日|资产_2|0.04|
| 二○ ○ ○年十一月一日|资产_2|0.04|
| 二零零零年十二月一日|资产_2|0.04|
| 二零零一年一月一日|资产_2| -0.03 |
我想计算每项资产从T - 12到T - 2的累计回报。因此,以2001-01-01为例,累计回报将是从2000-01-01到2000-11-01,并将其添加到新列中。
因此,对于2001年1月1日的ASSET_1,我得到的值为0.98 * 1.02 * 1.01 * 1.02 * 1.03 * 0.98 * 1.05 * 0.96 * 0.98 * 1.00 * 1.05 - 1 = 0.08
如果无法计算此类回报(NA值或没有足够的时间来计算此类数字),则累计回报将为NA。
如果不创建一堆滞后(返回)列,我就无法解决这个问题。有更简单的方法吗?

bwitn5fc

bwitn5fc1#

一个快速而粗略的解决方案(假设时间上没有间隙)是计算cumprod的累积乘积,然后对每个资产仅延迟第13行或更多行(T0):

library("dplyr")
library("magrittr")
library("tibble")
data <-
  structure(list(DATE = structure(c(10957, 10988, 11017, 11048, 
                                    11078, 11109, 11139, 11170,
                                    11201, 11231, 11262, 11292, 11323, 
                                    11017, 11048, 11078, 11109, 11139,
                                    11170, 11201, 11231, 11262, 
                                    11292, 11323), class = "Date"),
               CODE = c("ASSET_1", "ASSET_1", "ASSET_1", "ASSET_1", "ASSET_1",
                        "ASSET_1", "ASSET_1", "ASSET_1", "ASSET_1", "ASSET_1",
                        "ASSET_1", "ASSET_1", "ASSET_1",
                        "ASSET_2", "ASSET_2", "ASSET_2",
                        "ASSET_2", "ASSET_2", "ASSET_2", "ASSET_2", "ASSET_2",
                        "ASSET_2", "ASSET_2", "ASSET_2"),
               RETURN = c(-0.02, 0.02, 0.01, 0.02, 0.03, -0.02, 0.05, -0.04,
                       -0.02, 0, 0.05, 0.03, 0.01, NA, -0.02, NA, -0.03, 0.05, 0.02,
                       -0.03, 0.04, 0.04, 0.04, -0.03)),
            class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -24L))
want <-
  data %>%
  group_by(CODE) %>%
  arrange(DATE, .by_group = TRUE) %>%
  mutate(row_in_g = seq_len(n())) %>%
  mutate(cumulative_return = if_else(row_in_g >= 13,
                                     lag(cumprod(RETURN + 1), 2) - 1,
                                     NA_real_)) %>%
  select(-row_in_g) %>%
  ungroup()

其中:

> print(data, n = 30)
# A tibble: 24 x 3
   DATE       CODE    RETURN
   <date>     <chr>    <dbl>
 1 2000-01-01 ASSET_1  -0.02
 2 2000-02-01 ASSET_1   0.02
 3 2000-03-01 ASSET_1   0.01
 4 2000-04-01 ASSET_1   0.02
 5 2000-05-01 ASSET_1   0.03
 6 2000-06-01 ASSET_1  -0.02
 7 2000-07-01 ASSET_1   0.05
 8 2000-08-01 ASSET_1  -0.04
 9 2000-09-01 ASSET_1  -0.02
10 2000-10-01 ASSET_1   0   
11 2000-11-01 ASSET_1   0.05
12 2000-12-01 ASSET_1   0.03
13 2001-01-01 ASSET_1   0.01
14 2000-03-01 ASSET_2  NA   
15 2000-04-01 ASSET_2  -0.02
16 2000-05-01 ASSET_2  NA   
17 2000-06-01 ASSET_2  -0.03
18 2000-07-01 ASSET_2   0.05
19 2000-08-01 ASSET_2   0.02
20 2000-09-01 ASSET_2  -0.03
21 2000-10-01 ASSET_2   0.04
22 2000-11-01 ASSET_2   0.04
23 2000-12-01 ASSET_2   0.04
24 2001-01-01 ASSET_2  -0.03
> 
> print(want, n = 30)
# A tibble: 24 x 4
   DATE       CODE    RETURN cumulative_return
   <date>     <chr>    <dbl>             <dbl>
 1 2000-01-01 ASSET_1  -0.02           NA     
 2 2000-02-01 ASSET_1   0.02           NA     
 3 2000-03-01 ASSET_1   0.01           NA     
 4 2000-04-01 ASSET_1   0.02           NA     
 5 2000-05-01 ASSET_1   0.03           NA     
 6 2000-06-01 ASSET_1  -0.02           NA     
 7 2000-07-01 ASSET_1   0.05           NA     
 8 2000-08-01 ASSET_1  -0.04           NA     
 9 2000-09-01 ASSET_1  -0.02           NA     
10 2000-10-01 ASSET_1   0              NA     
11 2000-11-01 ASSET_1   0.05           NA     
12 2000-12-01 ASSET_1   0.03           NA     
13 2001-01-01 ASSET_1   0.01            0.0782
14 2000-03-01 ASSET_2  NA              NA     
15 2000-04-01 ASSET_2  -0.02           NA     
16 2000-05-01 ASSET_2  NA              NA     
17 2000-06-01 ASSET_2  -0.03           NA     
18 2000-07-01 ASSET_2   0.05           NA     
19 2000-08-01 ASSET_2   0.02           NA     
20 2000-09-01 ASSET_2  -0.03           NA     
21 2000-10-01 ASSET_2   0.04           NA     
22 2000-11-01 ASSET_2   0.04           NA     
23 2000-12-01 ASSET_2   0.04           NA     
24 2001-01-01 ASSET_2  -0.03           NA

相关问题