Корректировка Ньюи Уэста в таблице данных

#r #data.table #portfolio

#r #data.table #Портфолио

Вопрос:

У меня есть следующие данные.таблица

 PrevMonth   Portfolio   ExcessReturn
196306  Portfolio 1 -0.3035362
196306  Portfolio 10    -1.250766
196306  Portfolio 2 1.08474287
196306  Portfolio 3 -0.628247
196306  Portfolio 4 -0.2490027
196306  Portfolio 5 0.47310531
196306  Portfolio 6 0.36409036
196306  Portfolio 7 -0.8392494
196306  Portfolio 8 -0.5734843
196306  Portfolio 9 -1.9914358
196306  Portfolio LS    -0.9472298
196307  Portfolio 1 3.29524841
196307  Portfolio 10    6.47879571
196307  Portfolio 2 2.8880775
196307  Portfolio 3 4.35083011
196307  Portfolio 4 4.2523679
196307  Portfolio 5 4.30965798
196307  Portfolio 6 4.68137361
196307  Portfolio 7 4.34311633
196307  Portfolio 8 7.04824776
196307  Portfolio 9 7.35395871
196307  Portfolio LS    3.18354731
196308  Portfolio 1 -0.4837659
196308  Portfolio 10    -0.8704307
196308  Portfolio 2 -1.8642527
  

Что я хочу, чтобы иметь возможность выполнить t-тест, чтобы отклонить значение null, что среднемесячный избыточный доход равен нулю, и для этого я хочу выполнить корректировку Newey West с задержкой в 1 по ошибкам. Поэтому я регрессирую избыточную доходность по константе, сгруппированной по месяцам, и делаю корректировку Newey West.

Наконец, я хочу сообщить о скорректированной t-статистике Newey West и среднемесячной избыточной доходности для каждого портфеля.

Вот что я сделал:

 TS_Sample_Beta_Portfolio_Final<-Sample_Beta_Portfolio_Final[,list(coeftest(lm(ExcessReturn~1),
                                  vcov = NeweyWest(lm(ExcessReturn~1),lag = 12))),by=c("PrevMonth")]
  

где Sample_Beta_Portfolio содержит вышеуказанные данные.

Но, похоже, это не работает.

Любая помощь будет оценена!

Ответ №1:

Проблема в том, что ваш list вызов инкапсулирует вывод coeftest внутри списка, то есть списка с одним элементом class coeftest . Вместо этого вам нужен список с каждой отдельной статистикой, созданной coeftest . Таким образом, вы можете использовать as.list вместо:

 Sample_Beta_Portfolio_Final[, as.list(coeftest(lm(ExcessReturn~1), 
                                               vcov=NeweyWest(lm(ExcessReturn~1), 
                                                              lag=12))),
                            by=c("PrevMonth")]
  

Проблема с этим подходом заключается в том, что он не будет правильно называть ваш результат, поскольку as.list отбрасывает ваш dimnames . Альтернативой было бы написать fit функцию, которая переименовывает выходной список.

Сначала загрузите библиотеки и данные:

 library(data.table)
library(sandwich)
library(lmtest)

dat = fread("PrevMonth -Portfolio   ExcessReturn
196306-Portfolio 1 -0.3035362
196306-Portfolio 10    -1.250766
196306-Portfolio 2 1.08474287
196306-Portfolio 3 -0.628247
196306-Portfolio 4 -0.2490027
196306-Portfolio 5 0.47310531
196306-Portfolio 6 0.36409036
196306-Portfolio 7 -0.8392494
196306-Portfolio 8 -0.5734843
196306-Portfolio 9 -1.9914358
196306-Portfolio LS    -0.9472298
196307-Portfolio 1 3.29524841
196307-Portfolio 10    6.47879571
196307-Portfolio 2 2.8880775
196307-Portfolio 3 4.35083011
196307-Portfolio 4 4.2523679
196307-Portfolio 5 4.30965798
196307-Portfolio 6 4.68137361
196307-Portfolio 7 4.34311633
196307-Portfolio 8 7.04824776
196307-Portfolio 9 7.35395871
196307-Portfolio LS    3.18354731
196308-Portfolio 1 -0.4837659
196308-Portfolio 10    -0.8704307
196308-Portfolio 2 -1.8642527")
  

Затем определите fit функцию и примените ее к каждой группе:

 fit = function(x) {
  m = lm(ExcessReturn~1, x)
  v = NeweyWest(m, lag=12)
  ct = coeftest(m, vcov=v)
  out = as.list(ct)
  names(out) = dimnames(ct)[[2]]
  out[["r2"]] = summary(m)$r.squared
  out
}

dat[, fit(.SD), by="PrevMonth"]

#>           PrevMonth   Estimate Std. Error   t value     Pr(>|t|) r2
#> 1: 196306-Portfolio -0.4419102  0.1596251 -2.768425 1.984085e-02  0
#> 2: 196307-Portfolio  4.7441110  0.2203860 21.526374 1.044449e-09  0
#> 3: 196308-Portfolio -1.0728164  0.1614823 -6.643553 2.191480e-02  0
  

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

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

1. Спасибо! Можете ли вы сказать мне, как также получить R-квадрат из регрессии?

2. То же самое, что и любая другая линейная модель: просто добавьте это в свой fit список (в моем примере это называется out ): summary(m)$r.squared

3. Я сделал следующее, закомментировал строку имен, поскольку это, вероятно, не будет работать с R-squared . fit = функция (x) { m = lm(избыточный возврат ~ 1, x) v = Новый запад (m, задержка = 12) ct = коэффициент (m, vcov = v) out = as.list(ct, сводка (m) $ r.в квадрате) #имена (out) =dimnames(ct)[[2]] out } Beta_Stat<- Sample_Beta_Portfolio_Final[, fit(.SD), by=c(«Месяц»)] Он не привязывает R-квадрат к out.

4. Возможно, я был недостаточно ясен. fit Функция возвращает список с каждым из ваших столбцов. Вы хотите добавить новый столбец с помощью R2, поэтому все, что вам нужно сделать, это добавить новый элемент в список с правильным именем. Вы могли бы сделать это, назначив out[["r2"]] <- в fit функции. Я изменил приведенный выше код, чтобы показать, как это делается. Обратите внимание, что ваша регрессия довольно плохо соответствует данным, поэтому R2 равен нулю для каждой подгруппы в этих данных.