I have a time-series data set EuStockMarket. It contains observations for four stock markets from 1991 to 1998. I would like to extract each year separately.
data(EuStockMarkets)
str(EuStockMarkets)
I have a time-series data set EuStockMarket. It contains observations for four stock markets from 1991 to 1998. I would like to extract each year separately.
data(EuStockMarkets)
str(EuStockMarkets)
try this, using tsibble package:
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
The input, EuStockMarkets, in the question is a ts object so we assume the question is looking for a list of ts objects with one component per year. We provide the following solutions. In each case the years are used as the names of the components of the list.
1) zoo
Convert from ts to zoo class so that we can use split.zoo, split by year (the integer part of the time is the year) and convert back to ts. (If a list of zoo objects is ok then omit the lapply.)
library(zoo)
lapply(split(as.zoo(EuStockMarkets), as.integer(time(EuStockMarkets))), as.ts)
2) base
This solution is not as compact as (1) but if you need to avoid package dependencies it does not use any. It first splits the time vector into years and then for each component uses window to extract the sub-series for that year giving a list of ts objects.
spl <- split(time(EuStockMarkets), as.integer(time(EuStockMarkets)))
Map(window, start = Map(min, spl), end = Map(max, spl), list(EuStockMarkets))
Option 1
You can split the matrix-like ts object and reconstruct time series of each year by Map(). The final output is a list containing ts objects from 1991 to 1998. You can use the $ symbol to extract each year.
tm <- time(EuStockMarkets)
res1 <- Map(ts, split(as.data.frame(EuStockMarkets), floor(tm)),
tm[c(T, cycle(EuStockMarkets)[-1] == 1)],
frequency = frequency(EuStockMarkets))
Option 2
Another solution without splitting data, which may slightly improve efficiency.
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, ]
Output
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.