1111function _refs_pool (col:: AbstractArray , reftype:: Type{<:Integer} = UInt32)
1212 refs = refarray (col)
1313 pool = refpool (col)
14- labeled = pool != = nothing && ! (pool isa RotatingTimeRange)
14+ labeled = pool != = nothing
1515 if ! labeled
1616 refs, invpool, pool = _label (col, eltype (col), reftype)
1717 end
@@ -97,7 +97,7 @@ function cellrows(cols::VecColumnTable, refrows::IdDict)
9797 columns = Vector {AbstractVector} (undef, ncol)
9898 for i in 1 : ncol
9999 c = cols[i]
100- if typeof (c) <: ScaledArrOrSub
100+ if typeof (c) <: Union{ ScaledArrOrSub, RotatingTimeArray}
101101 columns[i] = similar (c, ncell)
102102 else
103103 columns[i] = Vector {eltype(c)} (undef, ncell)
@@ -127,76 +127,66 @@ function cellrows(cols::VecColumnTable, refrows::IdDict)
127127end
128128
129129"""
130- settime(data, timename; step, start, stop, reftype, rotation)
131- settime(time::AbstractArray; step, start, stop, reftype, rotation)
130+ settime(time::AbstractArray, step; start, stop, reftype, rotation)
132131
133132Convert a column of time values to a [`ScaledArray`](@ref)
134133for representing discretized time periods of uniform length.
135- Time values can be provided either as a table containing the relevant column or as an array.
134+ If `rotation` is specified (time values belong to multiple rotation groups),
135+ a [`RotatingTimeArray`](@ref) is returned with the `time` field
136+ being a [`ScaledArray`](@ref).
136137The returned array ensures well-defined time intervals for operations involving relative time
137138(such as [`lag`](@ref) and [`diff`](@ref)).
138139See also [`aligntime`](@ref).
139140
140141# Arguments
141- - `data`: a Tables.jl-compatible data table.
142- - `timename::Union{Symbol,Integer}`: the name of the column in `data` that contains time values.
143- - `time::AbstractArray`: the array containing time values (only needed for the alternative method).
142+ - `time::AbstractArray`: the array containing time values.
143+ - `step=nothing`: the length of each time interval; try `step=one(eltype(time))` if not specified.
144144
145145# Keywords
146- - `step=nothing`: the length of each time interval; try step=1 if not specified.
147146- `start=nothing`: the first element of the `pool` of the returned [`ScaledArray`](@ref).
148147- `stop=nothing`: the last element of the `pool` of the returned [`ScaledArray`](@ref).
149- - `reftype::Type{<:Signed}=Int32`: the element type of the reference values for the returned [`ScaledArray`](@ref).
150- - `rotation=nothing`: rotation groups in a rotating sampling design; use [`RotatingTimeValue`](@ref)s as reference values .
148+ - `reftype::Type{<:Signed}=Int32`: the element type of the reference values for the [`ScaledArray`](@ref).
149+ - `rotation=nothing`: rotation groups in a rotating sampling design.
151150"""
152- function settime (time:: AbstractArray ; step= nothing , start= nothing , stop= nothing ,
151+ function settime (time:: AbstractArray , step= nothing ; start= nothing , stop= nothing ,
153152 reftype:: Type{<:Signed} = Int32, rotation= nothing )
154153 T = eltype (time)
155154 T <: ValidTimeType && ! (T <: RotatingTimeValue ) ||
156155 throw (ArgumentError (" unaccepted element type $T from time column" ))
157156 step === nothing && (step = one (T))
158157 time = ScaledArray (time, start, step, stop; reftype= reftype)
159- if rotation != = nothing
160- refs = rotatingtime (rotation, time. refs)
161- rots = unique (rotation)
162- invpool = Dict {RotatingTimeValue{eltype(rotation), T}, eltype(refs)} ()
163- for (k, v) in time. invpool
164- for r in rots
165- rt = RotatingTimeValue (r, k)
166- invpool[rt] = RotatingTimeValue (r, v)
167- end
168- end
169- rmin, rmax = extrema (rots)
170- pool = RotatingTimeValue (rmin, first (time. pool)): scale (time): RotatingTimeValue (rmax, last (time. pool))
171- time = ScaledArray (RefArray (refs), pool, invpool)
172- end
158+ rotation === nothing || (time = RotatingTimeArray (rotation, time))
173159 return time
174160end
175161
176- function settime (data, timename:: Union{Symbol,Integer} ;
177- step= nothing , start= nothing , stop= nothing ,
178- reftype:: Type{<:Signed} = Int32, rotation= nothing )
179- checktable (data)
180- return settime (getcolumn (data, timename);
181- step= step, start= start, stop= stop, reftype= reftype, rotation= rotation)
182- end
183-
184162"""
163+ aligntime(col::AbstractArray, time::ScaledArrOrSub)
164+ aligntime(col::AbstractArray, time::RotatingTimeArray)
185165 aligntime(data, colname::Union{Symbol,Integer}, timename::Union{Symbol,Integer})
186166
187- Convert a column of time values indexed by `colname` from `data` table
188- to a [`ScaledArray`](@ref) with a `pool`
167+ Convert a column of time values `col` to a [`ScaledArray`](@ref) with a `pool`
189168that has the same first element and step size as the `pool` from
190- the [`ScaledArray`](@ref) indexed by `timename`.
169+ the [`ScaledArray`](@ref) `time`.
170+ If `time` is a [`RotatingTimeArray`](@ref) with the `time` field being a [`ScaledArray`](@ref),
171+ the returned array is also a [`RotatingTimeArray`](@ref)
172+ with the `time` field being the converted [`ScaledArray`](@ref).
173+ Alternative, the arrays may be specified with a Tables.jl-compatible `data` table
174+ and column indices `colname` and `timename`.
191175See also [`settime`](@ref).
192176
193177This is useful for representing all discretized time periods with the same scale
194178so that the underlying reference values returned by `DataAPI.refarray`
195179can be directly comparable across the columns.
196180"""
181+ aligntime (col:: AbstractArray , time:: ScaledArrOrSub ) = align (col, time)
182+ aligntime (col:: AbstractArray , time:: RotatingTimeArray ) =
183+ RotatingTimeArray (time. rotation, align (col, time. time))
184+ aligntime (col:: RotatingTimeArray , time:: RotatingTimeArray ) =
185+ RotatingTimeArray (time. rotation, align (col. time, time. time))
186+
197187function aligntime (data, colname:: Union{Symbol,Integer} , timename:: Union{Symbol,Integer} )
198188 checktable (data)
199- return align (getcolumn (data, colname), getcolumn (data, timename))
189+ return aligntime (getcolumn (data, colname), getcolumn (data, timename))
200190end
201191
202192"""
@@ -246,7 +236,7 @@ that is returned by [`settime`](@ref).
246236- `time::AbstractArray`: the array containing time values (only needed for the alternative method).
247237
248238# Keywords
249- - `step=nothing`: the length of each time interval; try step=1 if not specified.
239+ - `step=nothing`: the length of each time interval; try ` step=one(eltype(time))` if not specified.
250240- `reftype::Type{<:Signed}=Int32`: the element type of the reference values for [`PanelStructure`](@ref).
251241- `rotation=nothing`: rotation groups in a rotating sampling design; use [`RotatingTimeValue`](@ref)s as reference values.
252242
@@ -263,7 +253,7 @@ function setpanel(id::AbstractArray, time::AbstractArray; step=nothing,
263253 " id has length $(length (id)) while time has length $(length (time)) " ))
264254 refs, idpool, labeled = _refs_pool (id)
265255 labeled && (refs = copy (refs); idpool = copy (idpool))
266- time = settime (time; step= step, reftype= reftype, rotation= rotation)
256+ time = settime (time, step; reftype= reftype, rotation= rotation)
267257 trefs = refarray (time)
268258 tpool = refpool (time)
269259 # Multiply 2 to create enough gaps between id groups for the largest possible lead/lag
0 commit comments