@@ -54,12 +54,8 @@ for (A, V, M) in ((:CategoricalArray, :CategoricalVector, :CategoricalMatrix),
54
54
$As (A::NullableCategoricalArray; ordered::Bool=false)
55
55
56
56
If `A` is already a `CategoricalArray` or a `NullableCategoricalArray`, its levels
57
- and their order are preserved. The reference type is also preserved unless `compress`
58
- is provided. On the contrary, the `ordered` keyword argument takes precedence over
59
- the corresponding property of the input array, even when not provided.
60
-
61
- In all cases, a copy of `A` is made: use `convert` to avoid making copies when
62
- unnecessary.
57
+ are preserved; the same applies to the ordered property and the reference type unless
58
+ explicitly overriden.
63
59
""" ->
64
60
function $ A end
65
61
@@ -88,12 +84,8 @@ for (A, V, M) in ((:CategoricalArray, :CategoricalVector, :CategoricalMatrix),
88
84
$Vs (A::NullableCategoricalVector; ordered::Bool=false)
89
85
90
86
If `A` is already a `CategoricalVector` or a `NullableCategoricalVector`, its levels
91
- and their order are preserved. The reference type is also preserved unless `compress`
92
- is provided. On the contrary, the `ordered` keyword argument takes precedence over
93
- the corresponding property of the input array, even when not provided.
94
-
95
- In all cases, a copy of `A` is made: use `convert` to avoid making copies when
96
- unnecessary.
87
+ are preserved; the same applies to the ordered property and the reference type unless
88
+ explicitly overriden.
97
89
""" ->
98
90
function $ V end
99
91
@@ -118,16 +110,12 @@ for (A, V, M) in ((:CategoricalArray, :CategoricalVector, :CategoricalMatrix),
118
110
argument determines whether the array values can be compared according to the
119
111
ordering of levels or not (see [`isordered`](@ref)).
120
112
121
- $Ms (A::CategoricalMatrix; ordered::Bool=false )
122
- $Ms (A::NullableCategoricalMatrix; ordered::Bool=false )
113
+ $Ms (A::CategoricalMatrix; ordered::Bool=isordered(A) )
114
+ $Ms (A::NullableCategoricalMatrix; ordered::Bool=isordered(A) )
123
115
124
116
If `A` is already a `CategoricalMatrix` or a `NullableCategoricalMatrix`, its levels
125
- and their order are preserved. The reference type is also preserved unless `compress`
126
- is provided. On the contrary, the `ordered` keyword argument takes precedence over
127
- the corresponding property of the input array, even when not provided.
128
-
129
- In all cases, a copy of `A` is made: use `convert` to avoid making copies when
130
- unnecessary.
117
+ are preserved; the same applies to the ordered property and the reference type unless
118
+ explicitly overriden.
131
119
""" ->
132
120
function $ M end
133
121
@@ -187,11 +175,16 @@ for (A, V, M) in ((:CategoricalArray, :CategoricalVector, :CategoricalMatrix),
187
175
188
176
# # Constructors from arrays
189
177
190
- # This method is needed to ensure ordered!() only mutates a copy of A
191
- @compat (:: Type{$A{T, N, R}} ){T, N, R}(A:: $A{T, N, R} ; ordered= _isordered (A)) =
192
- ordered! (copy (A), ordered)
178
+ # This method is needed to ensure that a copy of the pool is always made
179
+ # so that ordered!() does not affect the original array
180
+ @compat function (:: Type{$A{T, N, R}} ){S, T, N, Q, R}(A:: CatArray{S, N, Q} ; ordered= _isordered (A))
181
+ res = convert ($ A{T, N, R}, A)
182
+ if res. pool === A. pool # convert() only makes a copy when necessary
183
+ res = $ A {T, N, R} (res. refs, deepcopy (res. pool))
184
+ end
185
+ ordered! (res, ordered)
186
+ end
193
187
194
- # Note this method is also used for CategoricalArrays when T, N or R don't match
195
188
@compat (:: Type{$A{T, N, R}} ){T, N, R}(A:: AbstractArray ; ordered= _isordered (A)) =
196
189
ordered! (convert ($ A{T, N, R}, A), ordered)
197
190
@@ -218,21 +211,21 @@ for (A, V, M) in ((:CategoricalArray, :CategoricalVector, :CategoricalMatrix),
218
211
$ A {T, 2} (A, ordered= ordered)
219
212
220
213
# From CategoricalArray (preserve R)
221
- @compat (:: Type{$A{T, N}} ){S, T, N, R}(A:: $A {S, N, R} ; ordered= _isordered (A)) =
214
+ @compat (:: Type{$A{T, N}} ){S, T, N, R}(A:: CatArray {S, N, R} ; ordered= _isordered (A)) =
222
215
$ A {T, N, R} (A, ordered= ordered)
223
- @compat (:: Type{$A{T}} ){S, T, N, R}(A:: $A {S, N, R} ; ordered= _isordered (A)) =
216
+ @compat (:: Type{$A{T}} ){S, T, N, R}(A:: CatArray {S, N, R} ; ordered= _isordered (A)) =
224
217
$ A {T, N, R} (A, ordered= ordered)
225
- @compat (:: Type{$A} ){T, N, R}(A:: $A {T, N, R} ; ordered= _isordered (A)) =
218
+ @compat (:: Type{$A} ){T, N, R}(A:: CatArray {T, N, R} ; ordered= _isordered (A)) =
226
219
$ A {T, N, R} (A, ordered= ordered)
227
220
228
- @compat (:: Type{$V{T}} ){S, T, R}(A:: $V{S , R} ; ordered= _isordered (A)) =
221
+ @compat (:: Type{$V{T}} ){S, T, R}(A:: CatArray{S, 1 , R} ; ordered= _isordered (A)) =
229
222
$ A {T, 1, R} (A, ordered= ordered)
230
- @compat (:: Type{$V} ){T, R}(A:: $V{T , R} ; ordered= _isordered (A)) =
223
+ @compat (:: Type{$V} ){T, R}(A:: CatArray{T, 1 , R} ; ordered= _isordered (A)) =
231
224
$ A {T, 1, R} (A, ordered= ordered)
232
225
233
- @compat (:: Type{$M{T}} ){S, T, R}(A:: $M{S , R} ; ordered= _isordered (A)) =
226
+ @compat (:: Type{$M{T}} ){S, T, R}(A:: CatArray{S, 2 , R} ; ordered= _isordered (A)) =
234
227
$ A {T, 2, R} (A, ordered= ordered)
235
- @compat (:: Type{$M} ){T, R}(A:: $M{T , R} ; ordered= _isordered (A)) =
228
+ @compat (:: Type{$M} ){T, R}(A:: CatArray{T, 2 , R} ; ordered= _isordered (A)) =
236
229
$ A {T, 2, R} (A, ordered= ordered)
237
230
238
231
@@ -270,21 +263,25 @@ for (A, V, M) in ((:CategoricalArray, :CategoricalVector, :CategoricalMatrix),
270
263
res
271
264
end
272
265
273
- # From CategoricalArray (preserve R)
274
- function convert {S, T, N, R} (:: Type{$A{T, N, R}} , A:: $A {S, N} )
266
+ # From CategoricalArray (preserve levels, ordering and R)
267
+ function convert {S, T, N, R} (:: Type{$A{T, N, R}} , A:: CatArray {S, N} )
275
268
if length (A. pool) > typemax (R)
276
269
throw (LevelsException {T, R} (levels (A)[typemax (R)+ 1 : end ]))
277
270
end
278
271
272
+ if $ A <: CategoricalArray && isa (A, NullableCategoricalArray)
273
+ any (x -> x == 0 , A. refs) && throw (NullException ())
274
+ end
275
+
279
276
refs = convert (Array{R, N}, A. refs)
280
277
pool = convert (CategoricalPool{T, R}, A. pool)
281
278
ordered! ($ A (refs, pool), isordered (A))
282
279
end
283
- convert {S, T, N, R} (:: Type{$A{T, N}} , A:: $A {S, N, R} ) =
280
+ convert {S, T, N, R} (:: Type{$A{T, N}} , A:: CatArray {S, N, R} ) =
284
281
convert ($ A{T, N, R}, A)
285
- convert {S, T, N, R} (:: Type{$A{T}} , A:: $A {S, N, R} ) =
282
+ convert {S, T, N, R} (:: Type{$A{T}} , A:: CatArray {S, N, R} ) =
286
283
convert ($ A{T, N, R}, A)
287
- convert {T, N, R} (:: Type{$A} , A:: $A {T, N, R} ) =
284
+ convert {T, N, R} (:: Type{$A} , A:: CatArray {T, N, R} ) =
288
285
convert ($ A{T, N, R}, A)
289
286
290
287
# R<:Integer is needed for this method to be considered more specific
@@ -658,37 +655,33 @@ this parameter will also introduce a type instability which can affect performan
658
655
the function where the call is made. Therefore, use this option with caution (the
659
656
one-argument version does not suffer from this problem).
660
657
661
- categorical{T}(A::CategoricalArray{T}[, compress::Bool]; ordered::Bool=false )
662
- categorical{T}(A::NullableCategoricalArray{T}[, compress::Bool]; ordered::Bool=false )
658
+ categorical{T}(A::CategoricalArray{T}[, compress::Bool]; ordered::Bool=isordered(A) )
659
+ categorical{T}(A::NullableCategoricalArray{T}[, compress::Bool]; ordered::Bool=isordered(A) )
663
660
664
661
If `A` is already a `CategoricalArray` or a `NullableCategoricalArray`, its levels
665
- are preserved. The reference type is also preserved unless `compress` is provided.
666
- On the contrary, the `ordered` keyword argument takes precedence over the
667
- corresponding property of the input array, even when not provided.
668
-
669
- In all cases, a copy of `A` is made: use `convert` to avoid making copies when
670
- unnecessary.
662
+ are preserved; the same applies to the ordered property, and to the reference type
663
+ unless `compress` is passed.
671
664
"""
672
665
function categorical end
673
666
674
- categorical (A:: AbstractArray ; ordered= false ) = CategoricalArray (A, ordered= ordered)
675
- categorical {T<:Nullable} (A:: AbstractArray{T} ; ordered= false ) =
667
+ categorical (A:: AbstractArray ; ordered= _isordered (A) ) = CategoricalArray (A, ordered= ordered)
668
+ categorical {T<:Nullable} (A:: AbstractArray{T} ; ordered= _isordered (A) ) =
676
669
NullableCategoricalArray (A, ordered= ordered)
677
670
678
671
# Type-unstable methods
679
- function categorical {T, N} (A:: AbstractArray{T, N} , compress; ordered= false )
672
+ function categorical {T, N} (A:: AbstractArray{T, N} , compress; ordered= _isordered (A) )
680
673
RefType = compress ? reftype (length (unique (A))) : DefaultRefType
681
674
CategoricalArray {T, N, RefType} (A, ordered= ordered)
682
675
end
683
- function categorical {T<:Nullable, N} (A:: AbstractArray{T, N} , compress; ordered= false )
676
+ function categorical {T<:Nullable, N} (A:: AbstractArray{T, N} , compress; ordered= _isordered (A) )
684
677
RefType = compress ? reftype (length (unique (A))) : DefaultRefType
685
678
NullableCategoricalArray {T, N, RefType} (A, ordered= ordered)
686
679
end
687
- function categorical {T, N, R} (A:: CategoricalArray{T, N, R} , compress; ordered= false )
680
+ function categorical {T, N, R} (A:: CategoricalArray{T, N, R} , compress; ordered= _isordered (A) )
688
681
RefType = compress ? reftype (length (levels (A))) : R
689
682
CategoricalArray {T, N, RefType} (A, ordered= ordered)
690
683
end
691
- function categorical {T, N, R} (A:: NullableCategoricalArray{T, N, R} , compress; ordered= false )
684
+ function categorical {T, N, R} (A:: NullableCategoricalArray{T, N, R} , compress; ordered= _isordered (A) )
692
685
RefType = compress ? reftype (length (levels (A))) : R
693
686
NullableCategoricalArray {T, N, RefType} (A, ordered= ordered)
694
687
end
0 commit comments