如何使所有月份在R中进行MIDAS回归的天数相同(例如22天)

时间:2015-03-02 02:26:21

标签: r time-series xts zoo forecasting

这是这两个帖子的后续问题。

How to deal with impossible dates for midasr package

https://stats.stackexchange.com/questions/77495/what-can-i-do-with-these-two-time-series

我需要在R的MIDAS包中使用mls函数将高频(每日)财务数据转换为低频(季度)宏观经济数据。

作者@mpiktas提到

  

您必须让所有月份都有相同的天数。然后   将频率设置为该数字。您可以通过丢弃数据来实现这一目标,   填充NAs或外推。

  

您可以使用zoo对象使填充更容易,但最终   应传递简单的数字向量。

我尝试了不同的搜索方式,并没有找到一种简单的方法来实现。

我使用dplyr让每个月有7天NA的31天。

# generate the date vector
library(midasr)
library(dplyr)
library(quantmod) 
tsxdate <- as.Date( paste(1979, rep(1:12, each=31), 1:31, sep="-") )

for (year in 1980:2015){
    tsxdate <- c(tsxdate,as.Date( paste(year, rep(1:12, each=31), 1:31, sep="-") ))
    }
# transform to dataframe
tsxdate.df <- as.data.frame(tsxdate)
# get the stock market index from yahoo
tsxindex <- getSymbols("^GSPTSE",src="yahoo", from = '1977-01-01', auto.assign = FALSE)
# merge two data frame to get each month with 31 days
tsx.df <- left_join(tsxdate.df, tsxindex)

我怀疑这是由于过多的NA造成的问题。

我将新的每日数据放入R中的MIDAS回归中。它不起作用。没有任何重量函数可以工作。

# since each month has 31 days. one quarter yy correspond to 93 days data. 
midas_r(midas_r(yy~trend+fmls(zz,30,93,nealmon) ,start=list(zz=rep(0,4))), Ofunction="nls")

你能告诉我如何让所有月份都有相同的天数吗?

更新

最后,我在zoo包中使用了aggregatefirst函数。它并不完美,但它的工作原理和速度都很快。 first将根据参数添加NA。

我仍然需要弄清楚如何将其纳入MIDAS回归。

# get data
tsx <- getSymbols("^GSPTSE",src="yahoo", from = '1977-01-01', auto.assign = FALSE)
# subset 
# generate a zoo object
library(zoo)
tsx.zoo <- zoo(tsx$GSPTSE.Adjusted)
# group by yearmonth and take first 22 days data.
days <-aggregate(tsx.zoo, as.yearmon, first, 22)

看起来像这样:每行是一个月,有22天的数据。

Jun 1979 1614.29      NA      NA      NA      NA      NA      NA      NA      NA      NA
Jul 1979 1614.29 1598.73 1579.88 1582.57 1582.27 1576.19 1559.23 1529.81 1533.50 1547.66
Aug 1979 1554.14 1556.94 1553.84 1553.84 1551.95 1561.23 1562.52 1571.00 1578.08 1580.28
Sep 1979 1685.11 1657.58 1690.10 1720.92 1716.53 1711.34 1722.71 1714.63 1727.50 1724.51
Oct 1979 1749.05 1767.40 1775.98 1786.35 1800.12 1800.12 1735.88 1685.21 1681.52 1670.65
Nov 1979 1599.33 1606.81 1596.54 1592.94 1574.49 1569.20 1583.97 1608.70 1611.00 1619.78

Jun 1979      NA      NA      NA      NA      NA      NA      NA      NA      NA      NA
Jul 1979 1556.94 1546.86 1548.46 1553.54 1542.07 1543.17 1552.85 1566.01 1573.99 1564.12
Aug 1979 1596.64 1602.82 1615.09 1636.53 1653.09 1660.97 1657.78 1665.46 1674.44 1674.64
Sep 1979 1714.73 1717.53 1732.59 1736.48 1731.19 1732.49 1746.75 1754.33 1747.45      NA
Oct 1979 1639.03 1613.19 1616.29 1635.34 1593.44 1533.40 1522.12 1534.49 1517.24 1523.92
Nov 1979 1628.55 1621.57 1624.36 1627.56 1620.27 1647.51 1677.93 1683.81 1690.70 1698.97

Jun 1979      NA      NA
Jul 1979 1554.14      NA
Aug 1979 1674.24 1675.43
Sep 1979      NA      NA
Oct 1979 1538.68 1552.25

再次更新:

@mpiktas提供了一种更好,更正确的方法。

  

每个周期开始时应填充1个NA。

     

2数据应该以响应变量的频率收集。在我的情况下,它是每季度。

他的功能可用于aggregate中的zoo功能。我想它在group_by中与dodplyr做同样的工作:拆分,操作并返回结果列表。我试试这个

tsxdaily <- aggregate(tsx.zoo, yearqtr, padd_nas, 66)

yearqtr是响应变量的频率。

1 个答案:

答案 0 :(得分:1)

以下是如何添加NA的一种可能方式。

首先,请注意MIDAS回归强调周期的最后一个值,因此您需要将NA放在前面,而不是放在后面。

假设我们有以下虚拟数据:

> dt <- data.frame(Day=1:10,Quarter=c(rep(1,6),rep(2,4)),value=1:10)
> dt
   Day Quarter value
1    1       1     1
2    2       1     2
3    3       1     3
4    4       1     4
5    5       1     5
6    6       1     6
7    7       2     7
8    8       2     8
9    9       2     9
10  10       2    10

在这个例子中有两个季度,第一个有6天,第二个4.假设我们想要协调数据,所以季度有7天(例如)。

定义在数据开头添加NA的简单函数:

padd_nas <- function(x, desired_length) {
    n <- length(x)
    if(n < desired_length) {
        c(rep(NA,desired_length-n),x)
    } else {
        tail(x,desired_length)
        }
}

这是一个说明此功能如何工作的示例:

> padd_nas(1:4,7)
[1] NA NA NA  1  2  3  4
> 

现在为每个季度添加NAs,并确保按天订购数据:

library(dplyr)
pdt <- dt %>% arrange(Day) %>% group_by(Quarter) %>% do(pv = padd_nas(.$value, 7))  

> pdt
Source: local data frame [2 x 2]
Groups: <by row>

  Quarter       pv
1       1 <int[7]>
2       2 <int[7]>  

要获取填充结果,只需使用unlist列上的pv

> pv <- pdt$pv %>% unlist
> pv
 [1] NA  1  2  3  4  5  6 NA NA NA  7  8  9 10

现在我们可以使用mls为MIDAS回归做好准备。假设每个季度只有最近3天相关:

> library(midasr)
> mls(pv, 0:2, 7)
     X.0/m X.1/m X.2/m
[1,]     6     5     4
[2,]    10     9     8

将其与原始数据dt进行比较。

这种方法可以推广用于任何低频和高频数据配置。