Я нашел несколько предыдущих вопросов по этой теме, особенно этот R: Сгруппированная линейная регрессия скользящего окна с помощью rollapply и ddply и R: Rolling/moving avg по группе , однако оба вопроса не дали точного решения проблемы, с которой я столкнулся. В настоящее время я пытаюсь оценить бета-версию CAPM по панельным данным, используя линейную регрессию. Итак, у меня есть разные фонды (в приведенном ниже примере я использовал 3 группы фондов), для которых я хотел бы рассчитать бета отдельно и для каждой строки. Чтобы выразить это более абстрактно: я пытаюсь выполнить линейную регрессию с движущимся окном по группе, чтобы оценить коэффициент для каждой строки на основе данных в окне.
install.packages("zoo","dplyr")
library(zoo);library(dplyr)
# Create dataframe
fund <- as.numeric(c(1,1,1,1,1,1,1,1,3,3,3,3,3,3,2,2,2,2,2,2,2))
return<- as.numeric(c(1:21))
benchmark <- as.numeric(c(1,13,14,20,14,32,4,1,5,7,1,0,7,1,-2,1,6,-7,9,10,9))
riskfree<-as.numeric(c(1,5,1,2,1,6,4,7,5,-5,10,0,3,1,2,1,6,7,8,9,10))
date <- as.Date(c("2010-07-30","2010-08-31","2010-09-30","2010-10-31","2010-11-30","2010-12-31","2011-01-30",
"2011-02-28","2010-07-31","2010-09-30","2010-10-31","2010-11-30","2010-12-31","2011-01-30",
"2010-07-30","2010-08-31","2010-09-30","2010-10-31","2010-11-30","2010-12-31","2011-01-30"))
funddata<-data.frame(date,fund,return,benchmark,riskfree)
# Creating variables of interest
funddata["ret_riskfree"]<-as.numeric(funddata$return-funddata$riskfree)
funddata["benchmark_riskfree"]<-as.numeric(funddata$benchmark-funddata$riskfree)
Я хочу сделать скользящую регрессию по двум столбцам df[6:7] для каждой группы, указанной в столбце «фонд». Расчет следует выполнять отдельно, чтобы в первых двух строках столбца бета для каждой группы фондов всегда было указано «NA». В конце концов, я хочу иметь полный фрейм данных со всеми группами фондов и всеми бета-значениями. Мне удалось придумать новый код, который работает, но довольно запутан и требует упорядочения данных по фонду и дате перед выполнением. Буду рад любым предложениям, как сделать его лучше.
funddata <- funddata[order(funddata$fund, funddata$date),]
beta_func <- function(x, benchmark_riskfree, ret_riskfree) {
a <- coef(lm(as.formula(paste(ret_riskfree, "~", benchmark_riskfree,-1)),
data = x))
return(a)
}
beta_list<-list()
for (i in c(1:3)){beta_list[[paste(i, sep="_")]]<- (rollapplyr(funddata[(funddata$fund==i),6:7], width = 3,
FUN = function(x) beta_func(as.data.frame(x), "benchmark_riskfree" , "ret_riskfree"),
by.column = FALSE,fill=NA))}
beta_list<-unlist(beta_list, recursive=FALSE)
funddata$beta<-beta_list