Smoothing Data with Dates

I have some data with an abscissa of DateTime type that I would like to smooth. I am familiar with SmoothingSplines so created my minimum non-working example with it.

I need to figure out how to put the DateTime into a type that SmoothingSplines understands. Once I have that I need to put it back into a DateTime type. Perhaps another smoothing package is more versatile?

Your input is appreciated.

using Dates
using Plots
using SmoothingSplines

dr = DateTime(2014, 01, 15):Day(1):DateTime(2014, 6, 1)  # DateTime range
length(dr)
 v = [x^1.35 + x*rand() for x in 1:length(dr)]  # ordinate data

 plot(dr,v)

 spl = fit(SmoothingSpline, dr, v, 5.0)
 spl = fit(SmoothingSpline, dump(dr), v, 5.0)

 vs = SmoothingSplines.predict(spl,dr)

 plot!(dr, v)

DateTime is a type that wraps the count of milliseconds from the Dates.jl epoch, which is a long time ago. To get a more useful value for your purpose, it makes sense to use counts relative to a more recent date. Your example suggests the information steps by Day rather than some smaller time unit. Assuming that is true,

using Dates
const Days2000 = Dates.value(Date(2000,1,1))
reltime(x::DateTime) = 
  Float64(Dates.value(Date(x)) - Days2000)
julia> const Epoch2000 = DateTime(2000,1,1)
2000-01-01T00:00:00

julia> const Date2000   = Date(Epoch2000)
2000-01-01

julia> const Days2000  = Dates.value(Date2000)
730120

julia> countdays(x::DateTime) = Dates.value(Date(x))  - Days2000
countdays (generic function with 1 method)

julia> reltime(x::DateTime) = Float64(countdays(x))
reltime (generic function with 1 method)

julia>

julia> datetime = DateTime(2014,1,1)
2014-01-01T00:00:00

julia> reltime(datetime)
5114.0

For smoothing splines, scaling the values (dividing by the value for the earliest date) is worthwhile and easy to invert.

Thank you for your help. Here is my now working MWE! It turns out that your hint of putting in a denominator for calculating the line fr was crucial at well.

using Dates
using Plots
using SmoothingSplines

dr = DateTime(2014, 01, 15):Day(1):DateTime(2014, 6, 1)  # DateTime range

length(dr)
 v = [x^1.35 + x*rand() for x in 1:length(dr)]  # ordinate data

 plot(dr,v)

 fr = Float64.(Dates.value.(dr) .- Dates.value(dr[1])) ./ Float64(Dates.value(DateTime(Day(1))))
 spl = fit(SmoothingSpline, fr, v, 100.0)
 
 vs = SmoothingSplines.predict(spl,fr)

 plot(dr, [v vs])
2 Likes