#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. Спасибо за ваши усилия, Анилгоял, это творческий способ решения проблемы