Combine methods
TimeSeries
supports merging two TimeArray
s, and squishing the timestamp to a longer-term interval while representing values that make sense.
merge
The merge
method performs joins between two TimeArray
s. The default behaviour is to perform an inner join, such that the resulting TimeArray
contains only timestamps that both TimeArray
s share, and values that correspond to that timestamp.
The AAPL
object from MarketData
has 8,336 rows of data from Dec 12, 1980 to Dec 31, 2013. If we merge it with the CAT
object, which contains 13,090 rows of data from Jan 2, 1962 to Dec 31, 2013 we might expect the resulting TimeArray
to have 8,336 rows of data, corresponding to the length of AAPL
. This assumes that every day that Apple Computer, Inc. traded, Caterpillar, Inc likewise traded. It turns out that this isn't true. CAT
did not trade on Sep 27, 1985 because Hurricane Glorio shut down the New York Stock Exchange. Apple Computer trades on the electronic NASDAQ and its trading was not halted on that day. The result of the merge should then be 8,335 rows:
julia> using TimeSeries
julia> using MarketData
julia> AppleCat = merge(AAPL, CAT);
julia> length(AppleCat)
8335
Left, right, and outer joins can also be performed by passing the corresponding symbol. These joins introduce NaN
values when data for a particular timestamp only exists in one of the series to be merged. For example:
julia> merge(op[1:3], cl[2:4], method = :left)
3×2 TimeArray{Float64, 2, Date, Matrix{Float64}} 2000-01-03 to 2000-01-05 ┌────────────┬────────┬───────┐ │ │ Open │ Close │ ├────────────┼────────┼───────┤ │ 2000-01-03 │ 104.88 │ NaN │ │ 2000-01-04 │ 108.25 │ 102.5 │ │ 2000-01-05 │ 103.75 │ 104.0 │ └────────────┴────────┴───────┘
julia> merge(op[1:3], cl[2:4], method = :right)
3×2 TimeArray{Float64, 2, Date, Matrix{Float64}} 2000-01-04 to 2000-01-06 ┌────────────┬────────┬───────┐ │ │ Open │ Close │ ├────────────┼────────┼───────┤ │ 2000-01-04 │ 108.25 │ 102.5 │ │ 2000-01-05 │ 103.75 │ 104.0 │ │ 2000-01-06 │ NaN │ 95.0 │ └────────────┴────────┴───────┘
julia> merge(op[1:3], cl[2:4], method = :outer)
4×2 TimeArray{Float64, 2, Date, Matrix{Float64}} 2000-01-03 to 2000-01-06 ┌────────────┬────────┬───────┐ │ │ Open │ Close │ ├────────────┼────────┼───────┤ │ 2000-01-03 │ 104.88 │ NaN │ │ 2000-01-04 │ 108.25 │ 102.5 │ │ 2000-01-05 │ 103.75 │ 104.0 │ │ 2000-01-06 │ NaN │ 95.0 │ └────────────┴────────┴───────┘
The merge
method allows users to specify the value for the meta
field of the merged object. When that value is not explicitly provided, merge
will concatenate the meta
field values, assuming these values to be strings. This covers the vast majority of use cases. In edge cases when users do not provide a meta
value and both field values are not strings, the merged object will take on Void
as its meta
field value:
julia> meta(AppleCat)
"AAPL_CAT"
julia> CatApple = merge(CAT, AAPL, meta = 47);
julia> meta(CatApple)
47
julia> meta(merge(AppleCat, CatApple))
Base.merge
— Functionmerge(ta1::TimeArray{T}, ta2::TimeArray{T}, [tas::TimeArray{T}...];
method = :inner, colnames = [...], padvalue = NaN)
Merge several TimeArray
s along with the time index.
Argument
method::Symbol
::inner
,:outer
,:left
or:right
.
collapse
The collapse
method allows for compressing data into a larger time frame. For example, converting daily data into monthly data. When compressing dates, something rational has to be done with the values that lived in the more granular time frame. To define what happens, a function call is made. In our example, we want to compress the daily cl
closing prices from daily to monthly. It makes sense for us to take the last
value known and have that represented with the corresponding timestamp. A non-exhaustive list of valid time methods is presented below.
Dates method | Time length |
---|---|
Dates.quarter | quarterly |
day | daily |
week | weekly, starting from Monday. |
month | monthly |
year | yearly |
hour | hourly |
minute | minutely |
second | secondly |
Showing this code in REPL:
julia> using TimeSeries
julia> using MarketData
julia> collapse(cl, month, last)
24×1 TimeArray{Float64, 1, Date, Vector{Float64}} 2000-01-31 to 2001-12-31 ┌────────────┬────────┐ │ │ Close │ ├────────────┼────────┤ │ 2000-01-31 │ 103.75 │ │ 2000-02-29 │ 114.62 │ │ 2000-03-31 │ 135.81 │ │ 2000-04-28 │ 124.06 │ │ 2000-05-31 │ 84.0 │ │ 2000-06-30 │ 52.38 │ │ 2000-07-31 │ 50.81 │ │ 2000-08-31 │ 60.94 │ │ ⋮ │ ⋮ │ │ 2001-06-29 │ 23.25 │ │ 2001-07-31 │ 18.79 │ │ 2001-08-31 │ 18.55 │ │ 2001-09-28 │ 15.51 │ │ 2001-10-31 │ 17.56 │ │ 2001-11-30 │ 21.3 │ │ 2001-12-31 │ 21.9 │ └────────────┴────────┘ 9 rows omitted
We can also supply the function that chooses the timestamp and the function that determines the corresponding value independently:
julia> using Statistics
julia> collapse(cl, month, last, mean)
24×1 TimeArray{Float64, 1, Date, Vector{Float64}} 2000-01-31 to 2001-12-31 ┌────────────┬─────────┐ │ │ Close │ ├────────────┼─────────┤ │ 2000-01-31 │ 103.359 │ │ 2000-02-29 │ 111.638 │ │ 2000-03-31 │ 128.503 │ │ 2000-04-28 │ 123.106 │ │ 2000-05-31 │ 100.81 │ │ 2000-06-30 │ 78.8891 │ │ 2000-07-31 │ 53.7585 │ │ 2000-08-31 │ 51.3122 │ │ ⋮ │ ⋮ │ │ 2001-06-29 │ 21.531 │ │ 2001-07-31 │ 21.4624 │ │ 2001-08-31 │ 18.6465 │ │ 2001-09-28 │ 16.602 │ │ 2001-10-31 │ 17.3222 │ │ 2001-11-30 │ 19.649 │ │ 2001-12-31 │ 21.695 │ └────────────┴─────────┘ 9 rows omitted
vcat
The vcat
method is used to concatenate time series: if you have two time series with the same columns, this function can merge them into a single object. Notably, it can be used to merge data that is split into multiple files. Its behaviour is quite different from merge
, which does not consider that its arguments are actually the same time series.
This concatenation is vertical (vcat
) because it does not create columns, it extends existing ones (which are represented vertically).
Base.vcat
— Methodvcat(tas)
Concatenate two $TimeArray$ into single object.
If there are duplicated timestamps, we will keep order as the function input.
julia> a = TimeArray([Date(2015, 10, 1), Date(2015, 10, 2), Date(2015, 10, 3)], [1, 2, 3]);
julia> b = TimeArray([Date(2015, 10, 2), Date(2015, 10, 3)], [4, 5]);
julia> [a; b]
5×1 TimeArray{Int64,1,Date,Array{Int64,1}} 2015-10-01 to 2015-10-03
│ │ A │
├────────────┼───────┤
│ 2015-10-01 │ 1 │
│ 2015-10-02 │ 2 │
│ 2015-10-02 │ 4 │
│ 2015-10-03 │ 3 │
│ 2015-10-03 │ 5 │
map
This function allows complete transformation of the data within the time series, with alteration on both the time stamps and the associated values. It works exactly like Base.map
: the first argument is a binary function (the time stamp and the values) that returns two values, respectively the new time stamp and the new vector of values. It does not perform any kind of compression like collapse
, but rather transformations.
The simplest example is to postpone all time stamps in the given time series, here by one year:
julia> using TimeSeries
julia> using Dates
julia> ta = TimeArray([Date(2015, 10, 01), Date(2015, 11, 01)], [15, 16])
2×1 TimeArray{Int64, 1, Date, Vector{Int64}} 2015-10-01 to 2015-11-01 ┌────────────┬────┐ │ │ A │ ├────────────┼────┤ │ 2015-10-01 │ 15 │ │ 2015-11-01 │ 16 │ └────────────┴────┘
julia> map((timestamp, values) -> (timestamp + Year(1), values), ta)
2×1 TimeArray{Int64, 1, Date, Vector{Int64}} 2016-10-01 to 2016-11-01 ┌────────────┬────┐ │ │ A │ ├────────────┼────┤ │ 2016-10-01 │ 15 │ │ 2016-11-01 │ 16 │ └────────────┴────┘