首页 > 解决方案 > 计算每月的权重差异

问题描述

我正在处理一些投资组合数据,但我对这种数据操作感到困惑。我有这个样本数据

df <- tibble(
  date = as.Date(c("2020-01-31", "2020-01-31", "2020-01-31", 
                   "2020-02-29", "2020-02-29", "2020-02-29",
                   "2020-03-31", "2020-03-31", "2020-03-31") ),
  id = c("KO", "AAPL", "MSFT",
         "KO", "AAPL", "GOOG", 
         "KO", "AAPL", "MSFT"),
  weight = c(0.3, 0.4, 0.3,
             0.5, 0.3, 0.2,
             0.6, 0.2, 0.2),
  
  `weight_change (desired column)` = c(NA, NA, NA,
                                       0.2, -0.1, 0.2,
                                       0.1, -0.1, 0.2)
) 

这些是样本投资组合中的头寸。投资组合每个月都会获得新的权重。我要计算的是每个项目的重量变化在前几个月的重量方面。在这个例子中,我们看到在 2 月底,KO 的当前权重为 0.5,比上个月增加了 0.2。AAPL 下降了 0.1,而 GOOG 取代了 MSFT,因此与上个月的变化是其当前的全部权重:0.2。如何设置变异,使其查找前一个日期的股票并计算权重之间的差异?

标签: rdplyr

解决方案


如果每个“id”的数据是每月的,我们可以做一个complete来考虑缺失的月份,然后做一个分组diff

library(dplyr)
library(tidyr)
library(zoo)    
df %>%
     mutate(yearmonth = as.Date(as.yearmon(date))) %>%
     group_by(id) %>% 
     complete(yearmonth = seq(first(yearmonth), last(yearmonth), by = '1 month')) %>%
     mutate(weight_change = if(n() == 1) weight else c(NA, diff(replace_na(weight, 0)))) %>%
     ungroup %>%
     select(names(df), weight_change) %>%
     filter(!is.na(date))
# A tibble: 9 x 5
#  date       id    weight `weight_change (desired column)` weight_change
#  <date>     <chr>  <dbl>                            <dbl>         <dbl>
#1 2020-01-31 AAPL     0.4                             NA          NA    
#2 2020-02-29 AAPL     0.3                             -0.1        -0.1  
#3 2020-03-31 AAPL     0.2                             -0.1        -0.100
#4 2020-02-29 GOOG     0.2                              0.2         0.2  
#5 2020-01-31 KO       0.3                             NA          NA    
#6 2020-02-29 KO       0.5                              0.2         0.2  
#7 2020-03-31 KO       0.6                              0.1         0.100
#8 2020-01-31 MSFT     0.3                             NA          NA    
#9 2020-03-31 MSFT     0.2                              0.2         0.2  

推荐阅读