Как мне рассчитать процент от портфеля акций, который был свернут, в R?

#r

#r

Вопрос:

Я провожу анализ портфеля акций и хочу проверить процент портфеля, который свернут между определенными датами.

Например: если в первом квартале 2020 года у меня в портфеле было 3 акции, которые называются «A, B, C», а в следующем квартале у меня будет три акции «A, B, D». Тогда 33% моего портфеля было свернуто между двумя датами. Названия моих акций — это коды CUSIP, которые являются идентификатором для акций США. Воспроизводимым примером является:

 cusip <- c("A1","A2","A3","A1","A2","B1","A1", "C1","C2")
Datecode <- c("201912","201912","201912","202003","202003","202003","202006","202006","202006")
Stocktable <- data_frame(cusip,Datecode)

 

Я хочу добавить процентное изменение между каждым кодом даты в новую таблицу, содержащую сводную статистику для моего портфолио.

Я уверен, что это возможно каким-то образом, но я потратил часы, пытаясь сделать это, не понимая этого правильно. Я надеюсь, что это сообщество может помочь!

Комментарии:

1. каков ваш желаемый результат?

2. Мой желаемый результат - таблица с двумя столбцами (dateCode и PercentChange) и одной строкой для каждого Datecode, а также процентное изменение с предыдущего квартала

3. Вы хотите сказать, что, поскольку 2 из 3 были одинаковыми в каждом квартале, это означает, что 33% были изменены??

4. Да, точно. И в моем воспроизводимом примере произошло изменение на 33% между первыми двумя кварталами и изменение на 66% между следующими двумя кварталами. Моя проблема в том, что у меня есть набор данных с более чем 30 позициями акций за каждый квартал, поэтому его не так просто рассчитать

Ответ №1:

Вы можете использовать table , а затем apply использовать diff и rowSums для внесения изменений.

 x <- table(Stocktable)
rowSums(apply(x, 1, diff) == 1) / colSums(x[,-ncol(x)]) * 100
#  202003   202006 
#33.33333 66.66667 
 

Ответ №2:

Как насчет этого ?

 library(dplyr)
library(purrr)

Stocktable %>%
  group_by(Datecode) %>%
  summarise(cusip = list(cusip)) %>%
  ungroup %>%
  mutate(lag_cusip = lag(cusip)) %>%
  transmute(Datecode,
            percentchange = map2_dbl(cusip, lag_cusip, 
                          ~length(setdiff(.x, .y))/length(.x)) * 100)

#  Datecode percentchange
#  <chr>            <dbl>
#1 201912           100  
#2 202003            33.3
#3 202006            66.7
 

Это предполагает, что ваши данные отсортированы по кварталам. Он определяет количество новых акций в этом квартале по сравнению с предыдущим и делится на общие запасы этого квартала.

Комментарии:

1. Действительно, хорошая стратегия, как всегда

Ответ №3:

Немного длинный подход, но будет работать

 library(dplyr)
library(tidyr)

Stocktable %>% mutate(d = 1) %>%
  pivot_wider(id_cols = Datecode, names_from = cusip, values_from = d, values_fill = 0) %>%
  mutate(d = rowSums(across(where(is.numeric)))) %>%
  mutate(across(-c(Datecode, d), ~ lag(., default = NA)*.)) %>%
  mutate(d2 = rowSums(across(-c(Datecode, d)))) %>%
  group_by(Datecode) %>%
  summarise(perc = paste(round(100*(1 - d2/d),2), "%"))

# A tibble: 3 x 2
  Datecode perc   
* <chr>    <chr>  
1 201912   NA %   
2 202003   33.33 %
3 202006   66.67 %
 

Или, что более логично, первая строка должна иметь 0% difference

 Stocktable %>% mutate(d = 1) %>%
  pivot_wider(id_cols = Datecode, names_from = cusip, values_from = d, values_fill = 0) %>%
  mutate(d = rowSums(across(where(is.numeric)))) %>%
  mutate(across(-c(Datecode, d), ~ lag(., default = 1)*.)) %>%
  mutate(d2 = rowSums(across(-c(Datecode, d)))) %>%
  group_by(Datecode) %>%
  summarise(perc = paste0(round(100*(1 - d2/d),2), "%"))

# A tibble: 3 x 2
  Datecode perc  
* <chr>    <chr> 
1 201912   0%    
2 202003   33.33%
3 202006   66.67%
 

Комментарии:

1. Спасибо за ваши усилия, Анилгоял, это творческий способ решения проблемы