A very common task in time series analysis is the task of subsetting a time series. Let us first load our working data sets and some libraries.

load(url("https://userpage.fu-berlin.de/soga/300/30100_data_sets/DWD_FUB.RData"))
library(xts)
library(lubridate)

For the sake of this tutorial we transform the monthly data set (ts.FUB.monthly) into a ts object. See the previous section for details.

start <- c(year(index(ts.FUB.monthly)[01]),
           month(index(ts.FUB.monthly)[01]))
ts.FUB.monthly = ts(coredata(ts.FUB.monthly),
                    start = start, 
                    frequency = 12)
class(ts.FUB.monthly)
## [1] "ts"
class(ts.FUB.daily)
## [1] "xts" "zoo"

In order to extract the oldest or newest observations we apply the head() and tail() function on both object types.

# ts object
head(ts.FUB.monthly, 10) # print the first 10 observations
##  [1]  2.8  1.1  5.2  9.0 15.1 19.0 21.4 18.8 13.9  9.0
# xts object
tail(ts.FUB.daily, 10) # print the last 10 observations
##            Temp Rain
## 2016-12-22  0.5  0.8
## 2016-12-23  2.6  0.0
## 2016-12-24  4.3  7.3
## 2016-12-25  7.2  5.6
## 2016-12-26  8.1  2.0
## 2016-12-27  6.2  5.6
## 2016-12-28  5.9  2.0
## 2016-12-29  3.1  0.0
## 2016-12-30 -0.6  0.0
## 2016-12-31 -0.1  0.0

That works out fine, however we realize that the xts object is aware of its time property.

With respect to the oldest or newest observations the xts object provides additional functionality. For instance, the functions first() and last() take an additional argument such as hours, days, weeks, months, quarters, and years to specify the range of oldest and newest observations, respectively.

xts::first(ts.FUB.daily,'3 days')
##            Temp Rain
## 1950-01-01 -3.2  2.2
## 1950-01-02  1.0 12.6
## 1950-01-03  2.8  0.5
xts::last(ts.FUB.daily, '1 week') # a week starts with monday
##            Temp Rain
## 2016-12-26  8.1  2.0
## 2016-12-27  6.2  5.6
## 2016-12-28  5.9  2.0
## 2016-12-29  3.1  0.0
## 2016-12-30 -0.6  0.0
## 2016-12-31 -0.1  0.0

Please note that the function names first() and last() are quite common words and thus, it may occur that another package in your namespace masked these function; thus we use the :: notation to state explicitly that we refer to the function from the xts package.

In addition to selecting the oldest or newest observations we may index our time series in the same manner as we are used from indexing vectors, matrices and data frames. This basic indexing works on both of our object types.

# ts object
ts.FUB.monthly[518:521]
## [1]  2.0  2.5 12.0 15.4
# xts object
ts.FUB.daily[78:81]
##            Temp Rain
## 1950-03-19 11.0    0
## 1950-03-20 10.3    0
## 1950-03-21  9.6    0
## 1950-03-22  9.1    0

As we may store multiple time series in a xts object, in our case the times series of daily temperature and daily rainfall, we may index the columns as well.

# xts object
ts.FUB.daily[78:81, 'Temp']
##            Temp
## 1950-03-19 11.0
## 1950-03-20 10.3
## 1950-03-21  9.6
## 1950-03-22  9.1

Further, the xts objects allow indexing bases on a date string ("yyyy-mm-dd"):

ts.FUB.daily["1989-07-12"]
##            Temp Rain
## 1989-07-12 20.3    0
ts.FUB.daily["2001-09"]
##            Temp Rain
## 2001-09-01 17.0  0.0
## 2001-09-02 14.7  1.5
## 2001-09-03 17.0  3.7
## 2001-09-04 14.4  1.7
## 2001-09-05 13.4  0.0
## 2001-09-06 14.4  0.0
## 2001-09-07 13.3  9.7
## 2001-09-08 12.2  0.6
## 2001-09-09 10.0 27.0
## 2001-09-10 12.9  6.4
## 2001-09-11 10.6 10.5
## 2001-09-12 11.8  1.6
## 2001-09-13 11.5  8.4
## 2001-09-14 11.3  2.0
## 2001-09-15 12.6  0.4
## 2001-09-16 11.4  2.4
## 2001-09-17 10.0  0.0
## 2001-09-18  9.5 24.1
## 2001-09-19 11.6  0.0
## 2001-09-20 12.0  4.3
## 2001-09-21 12.5  6.5
## 2001-09-22 11.3  2.3
## 2001-09-23 12.3  0.0
## 2001-09-24 11.3  4.9
## 2001-09-25 11.7  0.0
## 2001-09-26 11.0  0.0
## 2001-09-27  9.6 23.0
## 2001-09-28 12.1  0.0
## 2001-09-29 14.1  0.0
## 2001-09-30 13.0  4.5
ts.FUB.daily["1989-07/1989-07-12"]
##            Temp Rain
## 1989-07-01 17.8  6.9
## 1989-07-02 17.6  2.3
## 1989-07-03 13.8  0.6
## 1989-07-04 21.0  0.0
## 1989-07-05 22.4  0.0
## 1989-07-06 25.2  0.0
## 1989-07-07 25.3  0.0
## 1989-07-08 24.2  0.0
## 1989-07-09 21.8  0.2
## 1989-07-10 18.4  0.0
## 1989-07-11 17.9  0.0
## 1989-07-12 20.3  0.0

A xts object can also be indexed by any sequence. For example we may select all subsequent seven days in a row.

dates <- seq(as.Date('2010-01-15'), 
             as.Date('2010-04-12'), 
             by = 7)

ts.FUB.daily[dates]
##            Temp Rain
## 2010-01-15 -3.4  0.0
## 2010-01-22 -7.7  0.0
## 2010-01-29  0.2  4.2
## 2010-02-05  0.5  0.0
## 2010-02-12 -1.2  0.5
## 2010-02-19  2.1  0.4
## 2010-02-26  6.1  0.0
## 2010-03-05 -2.6  0.0
## 2010-03-12  1.7  3.2
## 2010-03-19 10.9  0.2
## 2010-03-26 14.8 10.2
## 2010-04-02  6.0  0.0
## 2010-04-09  8.7  0.2

Subsetting a particular part of the series

Another broadly used subsetting approach is to subset a particular part of the series. In R we use the window() function to achieve that task. The window() function works on both of our object types.

Le us apply the window() function to extract the monthly mean temperature for the station Berlin-Dahlem (FU) for the 10-year period from 1990 to 1999. Please note the nicely structured representation of our data given by the ts object.

# ts object
temp.1990.1999 <- window(ts.FUB.monthly, 
                         start = 1990, 
                         end = 1999)
temp.1990.1999
##       Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec
## 1990  3.9  6.2  7.9  9.1 14.9 16.4 17.4 18.8 12.3 10.5  5.3  1.1
## 1991  2.3 -2.3  6.8  8.2 10.5 14.5 20.6 18.3 15.1  9.0  4.7  1.7
## 1992  1.6  3.7  5.3  9.0 15.6 20.3 19.8 19.9 13.8  6.0  5.1  1.1
## 1993  2.4  0.4  4.3 11.7 16.4 16.0 16.5 16.2 12.7  8.8  0.6  3.5
## 1994  3.4 -0.4  5.9  9.6 13.7 16.3 22.8 18.5 13.8  7.3  6.8  3.8
## 1995  0.7  4.7  3.9  9.2 13.3 15.4 21.4 19.6 13.6 11.6  2.4 -2.5
## 1996 -3.7 -2.3  1.2 10.0 12.2 16.3 16.3 18.7 11.5  9.9  5.3 -2.4
## 1997 -2.1  4.4  5.4  7.0 13.8 17.7 19.2 21.3 14.6  8.4  4.1  2.3
## 1998  3.2  6.0  5.1 10.6 15.5 17.4 17.4 17.0 14.3  8.7  1.6  0.8
## 1999  3.2
plot(temp.1990.1999)

The xts object allows a more convenient approach for subsetting a particular part of the series.

# xts object
library(ggplot2)
autoplot(ts.FUB.daily["1990/1999",])