R как выбрать и выполнить вычисление для пары лет в каждой группе? (время перехода)

#r

#r

Вопрос:

У меня есть набор данных с 1963 по 2019 год и более 6000 компаний. Я хочу сгруппировать данные по компаниям, а затем рассчитать бета-версию за каждые два года. Например:

  1. сгруппируйте по компаниям, затем выберите 1963 и 1964, рассчитайте,
  2. для одной и той же компании выберите 1964 и 1965 годы, рассчитайте,

повторите описанные выше действия.

Итак, у каждой фирмы 55 бета-версий.

Я попытался использовать цикл for: (RET и MKT — это два столбца)

 result<-
  for (i in 1963:2017){
    filter(df,df$Year%in%c(i,i 1))%>%
      group_by(NAME)%>%
      summarise(beta=cov(RET,MKT)/var(MKT))
}
  

Но получите пустой результат. Может ли кто-нибудь помочь мне с этим? Спасибо.

Мой результат dput:

 structure(list(Year = c(1963, 1963, 1963, 1963, 1963, 1963, 1963, 
1963, 1963, 1963), COMNAM = c("A C F INDUSTRIES INC", "A J INDUSTRIES INC", 
"AMERICAN BRAKE SHOE CO", "NATIONAL ACME CO", "AIR REDUCTION INC", 
"ALLEGHENY POWER SYSTEMS INC", "ALLIED CHEMICAL CORP", "ALLIS CHALMERS MFG CO", 
"AMERICAN METAL CLIMAX INC", "AMERICAN BOSCH ARMA CORP"), MKT = c(0.051848, 
0.051848, 0.051848, 0.051848, 0.051848, 0.051848, 0.051848, 0.051848, 
0.051848, 0.051848), RET = c(0.047002, 0.034483, 0.056122, 0.057471, 
0.041475, 0.053846, 0.025424, 0.162393, 0.125, 0.157407)), row.names = c(915L, 
1936L, 4261L, 7852L, 12919L, 17179L, 18946L, 20649L, 21986L, 
25326L), class = "data.frame")
  

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

1. Не могли бы вы, пожалуйста, включить минимальные и репрезентативные выборочные данные (например, использовать dput(df[1:10, ]) , а затем включить выходные данные в свой пост). Это может быть примером использования для zoo::rollapply .

2. Конечно. Я добавляю результат dput для первых 10 строк.

3. Нет, это ежемесячный набор данных, поэтому для каждой компании есть 12 строк за каждый год. Я думаю, что использовать year может быть проще, поэтому я использую year (дата).

Ответ №1:

Вы можете попробовать это :

 library(dplyr)

result <- purrr::map_df(min(df$Year):(max(df$Year) - 1), function(i) {
             df %>%
              filter(Year%in% c(i,i 1)) %>%
              group_by(COMNAM)%>%
              summarise(year = paste(i, i   1, sep = '-'),
                        beta = cov(RET,MKT)/var(MKT))
             })
  

Это должно дать один объединенный набор result данных со year столбцом, в котором будет указано, beta для каких двух лет.

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

1. Большое вам спасибо! это работает отлично. Работает ли purr::map_df в этом формате: purr::map_df(диапазон для i, функция (i){вычисление})? и не могли бы вы подробнее объяснить разницу между использованием цикла for и purr::map_df? Спасибо

2. map_* варианты такие же, как для цикла, но поскольку вы используете dplyr , я подумал об использовании функции в tidyverse экосистеме. min(df$Year):(max(df$Year) - 1) создает диапазон лет, и для каждого из этих лет мы применяем вычисление в функции.

3. Имеет смысл. Спасибо за вашу помощь!!