diff --git a/src/apply.jl b/src/apply.jl index 6e5510f..8c8a2c0 100644 --- a/src/apply.jl +++ b/src/apply.jl @@ -132,6 +132,10 @@ julia> show(ts_weekly[1:10]) ``` """ function apply(ts::TSFrame, period::T, fun::V, index_at::Function=first; renamecols::Bool=true) where {T<:Dates.Period, V<:Function} + if !issorted(ts[:, :Index]) + throw(ArgumentError("The `Index` column in the TSFrame object is not sorted.")) + end + ep = endpoints(ts, period) j = 1 diff --git a/src/diff.jl b/src/diff.jl index 32102d1..5459242 100644 --- a/src/diff.jl +++ b/src/diff.jl @@ -73,12 +73,15 @@ julia> diff(ts, 3)[1:10] # difference over the third row ``` """ -# Diff +# Diff, Here we have used ArgumentError and not DomainError + function diff(ts::TSFrame, periods::Int = 1) if periods <= 0 - error("periods must be a postive int") + #error("periods must be a postive int") + throw(ArgumentError("`periods` must be a postive integer.")) end + ddf = ts.coredata[:, Not(:Index)] .- TSFrames.lag(ts, periods).coredata[:, Not(:Index)] insertcols!(ddf, 1, "Index" => ts.coredata[:, :Index]) TSFrame(ddf, :Index) -end +end \ No newline at end of file diff --git a/src/endpoints.jl b/src/endpoints.jl index 1aaee94..5629910 100644 --- a/src/endpoints.jl +++ b/src/endpoints.jl @@ -280,7 +280,8 @@ julia> datetimesecondsrandom[endpoints(datetimesecondsrandom, Hour(1))] """ function endpoints(values::AbstractVector, on::Function, k::Int=1) if (k <= 0) - throw(DomainError("`k` needs to be greater than 0")) + # throw(DomainError("`k` needs to be greater than 0")) + throw(ArgumentError("`k` must be a postive integer.")) end ex = Expr(:call, on, values) @@ -304,7 +305,20 @@ function endpoints(ts::TSFrame, on::Function, k::Int=1) endpoints(index(ts), on, k) end -function endpoints(timestamps::AbstractVector{T}, on::V)::Vector{Int} where {T<:Union{Date, DateTime, Time}, V<:Dates.Period} +function endpoints(timestamps::AbstractVector{T}, on::V)::Vector{Int} where {T<:Union{Date, DateTime, Time}, + V<:Union{ + Year, + Quarter, + Month, + Week, + Day, + Hour, + Minute, + Second, + Millisecond, + Microsecond, + Nanosecond + }} if (on.value <= 0) throw(DomainError("`on.value` needs to be greater than 0")) end diff --git a/src/getindex.jl b/src/getindex.jl index 196a986..2b9cdab 100644 --- a/src/getindex.jl +++ b/src/getindex.jl @@ -252,11 +252,12 @@ julia> ts[1, "x1"]; # same as above ### ### Inputs: row scalar, column scalar; Output: scalar + function Base.getindex(ts::TSFrame, i::Int, j::Int) return ts.coredata[i,j+1] end -function Base.getindex(ts::TSFrame, i::Int, j::Union{Symbol, String}) +function Base.getindex(ts::TSFrame, i::Int, j::Union{Symbol, AbstractString}) return ts.coredata[i, j] end @@ -265,7 +266,7 @@ function Base.getindex(ts::TSFrame, dt::T, j::Int) where {T<:TimeType} ts.coredata[idx, j+1] end -function Base.getindex(ts::TSFrame, dt::T, j::Union{String, Symbol}) where {T<:TimeType} +function Base.getindex(ts::TSFrame, dt::T, j::Union{AbstractString, Symbol}) where {T<:TimeType} idx = findfirst(x -> x == dt, index(ts)) ts.coredata[idx, j] end @@ -273,21 +274,32 @@ end ### Inputs: row scalar, column vector; Output: TSFrame function Base.getindex(ts::TSFrame, i::Int, j::AbstractVector{Int}) - TSFrame(ts.coredata[[i], Cols(:Index, j.+1)]) # increment: account for Index + TSFrame(ts.coredata[[i], Cols(:Index, j.+1)]) # increment: account for Index end -function Base.getindex(ts::TSFrame, i::Int, j::AbstractVector{T}) where {T<:Union{String, Symbol}} - TSFrame(ts.coredata[[i], Cols(:Index, j)]) + +function Base.getindex(ts::TSFrame, i::Int, j::AbstractVector{T}) where {T<:Union{AbstractString, Symbol}} + if length(unique(map(x -> typeof(x), j))) == 1 + TSFrame(ts.coredata[[i], Cols(:Index, j)]) + else + throw(ArgumentError("The column vector cannot contain both String and Symbol types.")) + end end + function Base.getindex(ts::TSFrame, dt::T, j::AbstractVector{Int}) where {T<:TimeType} idx = findfirst(x -> x == dt, index(ts)) ts[idx, j] end -function Base.getindex(ts::TSFrame, dt::D, j::AbstractVector{T}) where {D<:TimeType, T<:Union{String, Symbol}} +function Base.getindex(ts::TSFrame, dt::D, j::AbstractVector{T}) where {D<:TimeType, T<:Union{AbstractString, Symbol}} idx = findfirst(x -> x == dt, index(ts)) - ts[idx, j] + if length(unique(map(x -> typeof(x), j))) == 1 + ts[idx, j] + else + throw(ArgumentError("The column vector cannot contain both AbstractString and Symbol types.")) + end + end ### @@ -302,7 +314,8 @@ function Base.getindex(ts::TSFrame, i::AbstractVector{Int}, j::Int) ts.coredata[i, j+1] # increment: account for Index end -function Base.getindex(ts::TSFrame, i::AbstractVector{Int}, j::Union{String, Symbol}) + +function Base.getindex(ts::TSFrame, i::AbstractVector{Int}, j::Union{AbstractString, Symbol}) ts.coredata[i, j] end @@ -314,12 +327,18 @@ function Base.getindex(ts::TSFrame, dt::AbstractVector{T}, j::Int) where {T<:Tim ts[idx, j] end -function Base.getindex(ts::TSFrame, dt::AbstractVector{T}, j::Union{String, Symbol}) where {T<:TimeType} + +function Base.getindex(ts::TSFrame, dt::AbstractVector{T}, j::Union{AbstractString, Symbol}) where {T<:TimeType} idx = map(d -> findfirst(x -> x == d, index(ts)), dt) if length(idx) == 0 return nothing + else + if length(unique(map(x -> typeof(x), j))) == 1 + ts[idx, j] + else + throw(ArgumentError("The column vector cannot contain both AbstractString and Symbol types.")) + end end - ts[idx, j] end ### @@ -328,10 +347,16 @@ function Base.getindex(ts::TSFrame, i::AbstractVector{Int}, j::AbstractVector{In TSFrame(ts.coredata[i, Cols(:Index, j.+1)]) # increment: account for Index end -function Base.getindex(ts::TSFrame, i::AbstractVector{Int}, j::AbstractVector{T}) where {T<:Union{String, Symbol}} - TSFrame(ts.coredata[i, Cols(:Index, j)]) + +function Base.getindex(ts::TSFrame, i::AbstractVector{Int}, j::AbstractVector{T}) where {T<:Union{AbstractString, Symbol}} + if length(unique(map(x -> typeof(x), j))) == 1 + TSFrame(ts.coredata[i, Cols(:Index, j)]) + else + throw(ArgumentError("The column vector cannot contain both AbstractString and Symbol types.")) + end end + function Base.getindex(ts::TSFrame, dt::AbstractVector{T}, j::AbstractVector{Int}) where {T<:TimeType} idx = map(d -> findfirst(x -> x == d, index(ts)), dt) if length(idx) == 0 @@ -340,9 +365,15 @@ function Base.getindex(ts::TSFrame, dt::AbstractVector{T}, j::AbstractVector{Int ts[idx, j] end -function Base.getindex(ts::TSFrame, dt::AbstractVector{D}, j::AbstractVector{T}) where {D<:TimeType, T<:Union{String, Symbol}} + +function Base.getindex(ts::TSFrame, dt::AbstractVector{D}, j::AbstractVector{T}) where {D<:TimeType, T<:Union{AbstractString, Symbol}} idx = map(d -> findfirst(x -> x == d, index(ts)), dt) - ts[idx, j] + if length(unique(map(x -> typeof(x), j))) == 1 + ts[idx, j] + else + throw(ArgumentError("The column vector cannot contain both AbstractString and Symbol types.")) + end + end ### @@ -362,7 +393,8 @@ function Base.getindex(ts::TSFrame, i::UnitRange, j::Int) ts[collect(i), j] end -function Base.getindex(ts::TSFrame, i::UnitRange, j::Union{String, Symbol}) + +function Base.getindex(ts::TSFrame, i::UnitRange, j::Union{AbstractString, Symbol}) ts[collect(i), j] end ### @@ -372,8 +404,14 @@ function Base.getindex(ts::TSFrame, i::UnitRange, j::AbstractVector{Int}) ts[collect(i), j] end -function Base.getindex(ts::TSFrame, i::UnitRange, j::AbstractVector{T}) where {T<:Union{String, Symbol}} - ts[collect(i), j] + +function Base.getindex(ts::TSFrame, i::UnitRange, j::AbstractVector{T}) where {T<:Union{AbstractString, Symbol}} + if length(unique(map(x -> typeof(x), j))) == 1 + ts[collect(i), j] + else + throw(ArgumentError("The column vector cannot contain both AbstractString and Symbol types.")) + end + end ### @@ -476,7 +514,8 @@ function Base.getindex(ts::TSFrame, ::Colon, j::Int) ts[1:TSFrames.nrow(ts), j] end -function Base.getindex(ts::TSFrame, ::Colon, j::Union{String, Symbol}) + +function Base.getindex(ts::TSFrame, ::Colon, j::Union{AbstractString, Symbol}) ts[1:TSFrames.nrow(ts), j] end ### @@ -486,8 +525,13 @@ function Base.getindex(ts::TSFrame, ::Colon, j::AbstractVector{Int}) ts[1:TSFrames.nrow(ts), j] end -function Base.getindex(ts::TSFrame, ::Colon, j::AbstractVector{T}) where {T<:Union{String, Symbol}} - ts[1:TSFrames.nrow(ts), j] +function Base.getindex(ts::TSFrame, ::Colon, j::AbstractVector{T}) where {T<:Union{AbstractString, Symbol}} + if length(unique(map(x -> typeof(x), j))) == 1 + ts[1:TSFrames.nrow(ts), j] + else + throw(ArgumentError("The column vector cannot contain both AbstractString and Symbol types.")) + end + end ### diff --git a/src/subset.jl b/src/subset.jl index fdce095..a795a7e 100644 --- a/src/subset.jl +++ b/src/subset.jl @@ -5,7 +5,7 @@ subset(ts::TSFrame, from::T, to::T) where {T<:Union{Int, TimeType}} ``` -Create a subset of `ts` based on the `Index` starting `from` +Create a subset of `ts` based on the [`Index`](@ref) starting `from` (inclusive) till `to` (inclusive). # Examples @@ -139,6 +139,7 @@ julia> subset(ts,Date("2022-9-27"),:) """ function subset(ts::TSFrame, from::T, to::T) where {T<:Union{Int, TimeType}} + #TSFrame(DataFrames.subset(ts.coredata, :Index => x -> from .<= x .<= to)) TSFrame(DataFrames.subset(ts.coredata, :Index => x -> from .<= x .<= to)) end diff --git a/src/utils.jl b/src/utils.jl index b18ac65..e7012c8 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -537,6 +537,7 @@ function _check_consistency(ts::TSFrame)::Bool issorted(index(ts)) end + """ ```julia