【问题标题】:Rolling cumulative product with NAs R使用 NAs R 滚动累积产品
【发布时间】:2021-02-03 04:52:52
【问题描述】:

我有以下数据库 (X),其中包含一段时间内的每月股票收益。我显示前 12 行。股票收益可以包含随机的 NA。

Obs. Asset Date Ret
 1 DJ    1997-10-06   NA    
 2 DJ    1997-10-07   NA    
 3 DJ    1997-10-08   -1.13 
 4 DJ    1997-10-09   -0.136
 5 DJ    1997-10-10   NA    
 6 DJ    1997-10-14   NA    
 7 DJ    1997-10-15   NA    
 8 DJ    1997-10-16   -0.225
 9 DJ    1997-10-17   -0.555
10 DJ    1997-10-20   NA    
11 DJ    1997-10-21    0.102
12 DJ    1997-10-22   NA    

我想计算 5 天窗口内的累积回报。所以我从观察 5 中获得了累积回报,忽略了 NA。只有当窗口内的收益也为 NA 时,累积收益才会为 NA。

我试过了:

Y <- Y %>%
  mutate(product = (as.numeric(rollapply(1 + ret/100, 5, prod,
                                        partial = TRUE, na.rm = TRUE, align = "right"))-1)*100)

这会产生不希望的结果:

> 1 1997-10-06  DJ  NA  0.000000000 
> 2 1997-10-07  DJ  NA  0.000000000
> 3 1997-10-08  DJ  -1.1277917526   -1.127791753
> 4 1997-10-09  DJ  -0.1364864885   -1.262738958
> 5 1997-10-10  DJ  NA  -1.262738958 
> 6 1997-10-14  DJ  NA  -1.262738958
> 7 1997-10-15  DJ  NA  -1.262738958
> 8 1997-10-16  DJ  -0.2250333841   -0.361212732
> 9 1997-10-17  DJ  -0.5545946845   -0.778380045
> 10    1997-10-20  DJ  NA  -0.778380045
> 11    1997-10-21  DJ  0.1022404757    -0.676935389
> 12    1997-10-22  DJ  NA  -0.676935389

我想在第 5 次观察之前获得 NA,所以第 1-4 行是 NA。第 5 行计算第 1-5 行的累计回报,第 6 行计算第 2-6 行的累计回报,以此类推。

代表:

X <- data.frame(Date=c("1997-10-06" ,"1997-10-07", "1997-10-08" ,"1997-10-09", "1997-10-10",
"1997-10-14", "1997-10-15" ,"1997-10-16", "1997-10-17","1997-10-20", "1997-10-21" ,"1997-10-22"),
    ret=c(NA,NA,-1.1277918,-0.1364865, NA , NA ,  NA ,-0.2250334 ,-0.5545947, NA, 0.1022405, NA))

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以将NA 替换为0,然后使用zoo::rollsum 默认行为:

    library(zoo)
    library(tidyr)
    library(dplyr)
    
    df %>% 
      dplyr::mutate(ret = zoo::rollsum(tidyr::replace_na(ret, 0), k = 5, na.pad = T, align = "right))
    
             Date        ret
    1  1997-10-06         NA
    2  1997-10-07         NA
    3  1997-10-08         NA
    4  1997-10-09         NA
    5  1997-10-10 -1.2642783
    6  1997-10-14 -1.2642783
    7  1997-10-15 -1.2642783
    8  1997-10-16 -0.3615199
    9  1997-10-17 -0.7796281
    10 1997-10-20 -0.7796281
    11 1997-10-21 -0.6773876
    12 1997-10-22 -0.6773876
    

    【讨论】:

    • 谢谢您,好心的先生。
    【解决方案2】:

    这里有一些代码可以获取您的数据,将ret 中的所有NA 更改为0,然后使用RcppRolltidyverse 包计算滚动的5 周期总和。

    # Load libraries
    library('RcppRoll')
    library('tidyverse')
    
    # Load data
    df <- data.frame(Date=c("1997-10-06" ,"1997-10-07", "1997-10-08" ,"1997-10-09", "1997-10-10",
    "1997-10-14", "1997-10-15" ,"1997-10-16", "1997-10-17","1997-10-20", "1997-10-21" ,"1997-10-22"),
    ret=c(NA,NA,-1.1277918,-0.1364865, NA , NA ,  NA ,-0.2250334 ,-0.5545947, NA, 0.1022405, NA), stringsAsFactors = F)
    
    # Change NA's to Zeros
    df[is.na(df[,2]),2] <- 0
    
    # Calculate Rolling Sum
    df_new <- df %>% mutate(rollsum = roll_sum(ret, n=5, align = 'right', fill=NA))
    

    【讨论】:

      猜你喜欢
      • 2017-03-07
      • 1970-01-01
      • 2017-03-09
      • 1970-01-01
      • 2021-06-18
      • 2017-05-25
      • 1970-01-01
      • 2019-03-30
      相关资源
      最近更新 更多