Скользящая регрессия с расширяющимся окном

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

Например, во фрейме данных ниже я хотел бы извлечь коэффициенты lm (return ~ regress1 + regress 2), сгруппированные по категории K, используя все строки до интересующей строки. Таким образом, для строки 2 набор данных для регрессии будет строками 1: 2, для строки 3 будет строки 1: 3, для строки 4 будет просто строка 4, поскольку это первая строка с категориальной переменной K = B.

myinput <- data.frame(K = c("A", "A", "A", "B", "B", "B", "C", "C", "C"), 
                      date = c(1:3) , return = rnorm(9), regress1 = rnorm(9), regress2 = rnorm(9))

Я нашел здесь очень полезную ветку по этой теме: Скользящая регрессия с расширяющимся окном в R, но мне сложно применить его к моему набору данных.

Если бы кто-нибудь мог помочь мне понять, как мне нужно адаптировать используемый ими подход, я был бы очень признателен. Спасибо.


person Denise    schedule 02.03.2020    source источник


Ответы (1)


Используя myinput, воспроизводимо показанный в Примечании в конце, определите функцию reg для выполнения регрессии. Затем используйте rollapplyr с аргументом width, равным date, используя тот факт, что date равно 1, 2, 3 и т. Д. Внутри группы и, таким образом, равно количеству строк, по которым выполняется регрессия. Наконец cbind результат возвращается к исходному фрейму данных.

library(zoo)

reg <- function(x) coef(lm(as.data.frame(x)))

r <- rollapplyr(zoo(myinput[3:5]), myinput$date, reg, by.column=FALSE, coredata=FALSE)
cbind(myinput, coef = coredata(r))

давая:

  K date      return   regress1   regress2 coef.(Intercept) coef.regress1 coef.regress2
1 A    1 -0.56047565 -0.4456620  0.7013559      -0.56047565            NA            NA
2 A    2 -0.23017749  1.2240818 -0.4727914      -0.47231761     0.1978137            NA
3 A    3  1.55870831  0.3598138 -1.0678237       0.15985654    -0.9479906    -1.6294374
4 B    1  0.07050839  0.4007715 -0.2179749       0.07050839            NA            NA
5 B    2  0.12928774  0.1106827 -1.0260044       0.15171486    -0.2026254            NA
6 B    3  1.71506499 -0.5558411 -0.7288912       1.05050327    -2.0789081     0.6735997
7 C    1  0.46091621  1.7869131 -0.6250393       0.46091621            NA            NA
8 C    2 -1.26506123  0.4978505 -1.6866933      -1.93165311     1.3389399            NA
9 C    3 -0.68685285 -1.9666172  0.8377870      -0.14625482     0.6376389     0.8515213

Примечание

set.seed необходимо использовать до использования случайных данных, чтобы результат был воспроизводимым. Мы использовали это:

set.seed(123)
myinput <- data.frame(K = c("A", "A", "A", "B", "B", "B", "C", "C", "C"), 
  date = 1:3, return = rnorm(9), regress1 = rnorm(9), regress2 = rnorm(9))
person G. Grothendieck    schedule 03.03.2020
comment
Спасибо @G. Гротендик. Выглядит отлично. Однако, когда я применяю rollapply, я получаю следующую ошибку: Ошибка в Math.POSIXt (length.out): «потолок» не определен для объектов POSIXt. Может быть, я должен добавить, что даты, которые я использую, на самом деле не в формате 1, 2, 3, а 92 квартала с 31 марта 1997 года по 30 июня 1997 года, 30 сентября 1997 года и т. Д. Для каждой категории (вероятно, следует включил это в вопрос, извините за это). Может быть, поэтому я получаю ошибку? - person Denise; 03.03.2020
comment
Если в каждой группе одинаковое количество строк, k (где k = nrow (myinput) / nlevels (myinput $ K), что равно 3 в вопросе), тогда столбец даты должен быть 1: k. внутри группы использовать код дословно. Если нет, то myinput $ w ‹- 1: k можно использовать для создания столбца w, который можно использовать вместо даты. как значение аргумента width = в rollapplyr. Если группы имеют разный размер (или даже если нет), мы можем использовать w ‹- с (myinput, ave (seq_along (K), K, FUN = seq_along)) - person G. Grothendieck; 03.03.2020