如何从R中的时间序列数据集中提取每年的数据



我有一个时间序列数据集EuStockMarket。它包含了对1991年至1998年四个股票市场的观察。我想每年单独摘录。

data(EuStockMarkets)
str(EuStockMarkets)

问题中的输入EuStockMarkets是一个ts对象,因此我们假设该问题是在寻找一个每年包含一个组件的ts对象列表。我们提供以下解决方案。在每种情况下,年份都被用作列表中各组成部分的名称。

1(动物园

从ts转换为zoo类,这样我们就可以使用split.zoo,按年份拆分(时间的整数部分是年(,然后转换回ts。(如果zoo对象列表可以,那么省略lapply。(

library(zoo)
lapply(split(as.zoo(EuStockMarkets), as.integer(time(EuStockMarkets))), as.ts)

2(基础

这个解决方案不像(1(那样紧凑,但如果您需要避免包依赖性,它不会使用任何依赖性。它首先将时间向量拆分为年,然后使用window为每个组件提取该年的子序列,给出ts对象的列表。

spl <- split(time(EuStockMarkets), as.integer(time(EuStockMarkets)))
Map(window, start = Map(min, spl), end = Map(max, spl), list(EuStockMarkets))

使用tsible包试试这个:

library(tsibble)
tsbl <- as_tsibble(EuStockMarkets)
tsbl %>%
group_by_key() %>%
index_by(year = ~ year(.))
# A tsibble: 7,440 x 4 [1s] <UTC>
# Key:       key [4]
# Groups:    key @ year [32]
index               key   value  year
<dttm>              <chr> <dbl> <dbl>
1 1991-07-01 02:18:33 DAX   1629.  1991
2 1991-07-02 12:00:00 DAX   1614.  1991
3 1991-07-03 21:41:27 DAX   1607.  1991
4 1991-07-05 07:22:55 DAX   1621.  1991
5 1991-07-06 17:04:22 DAX   1618.  1991
6 1991-07-08 02:46:21 DAX   1611.  1991
7 1991-07-09 12:27:49 DAX   1631.  1991
8 1991-07-10 22:09:16 DAX   1640.  1991
9 1991-07-12 07:50:44 DAX   1635.  1991
10 1991-07-13 17:32:11 DAX   1646.  1991
# ... with 7,430 more rows

选项1

您可以像ts对象一样拆分矩阵,并通过Map()重建每年的时间序列。最后的输出是一个包含1991年到1998年的ts对象的列表。您可以使用$符号每年提取一次。

tm <- time(EuStockMarkets)
res1 <- Map(ts, split(as.data.frame(EuStockMarkets), floor(tm)),
tm[c(T, cycle(EuStockMarkets)[-1] == 1)],
frequency = frequency(EuStockMarkets))

选项2

另一种不拆分数据的解决方案,这可能会略微提高效率。

cyc <- cycle(EuStockMarkets)[-1] ; tm <- time(EuStockMarkets)
res2 <- Map(window, list(EuStockMarkets), tm[c(T, cyc == 1)], tm[c(cyc == 1, T)])
names(res2) <- sapply(res2, start)[1, ]

输出

res1$`1991`
# Time Series:
# Start = c(1991, 130) 
# End = c(1991, 260) 
# Frequency = 260 
#              DAX    SMI    CAC   FTSE
# 1991.496 1628.75 1678.1 1772.8 2443.6
# 1991.500 1613.63 1688.5 1750.5 2460.2
# 1991.504 1606.51 1678.6 1718.0 2448.2
# etc.
res1$`1998`
# Time Series:
# Start = c(1998, 1) 
# End = c(1998, 169) 
# Frequency = 260 
#              DAX    SMI    CAC   FTSE
# 1998.000 4132.79 6044.7 2858.1 5049.8
# 1998.004 4132.79 6046.7 2874.1 5013.9
# 1998.008 4132.79 6046.7 2874.1 5013.9
# etc.

最新更新