@@ -19,10 +19,34 @@ function reftype(sz::Int)
19
19
end
20
20
end
21
21
22
+ # This check is only there to print a user-friendly warning before
23
+ # a TypeError is thrown due to restrictions in the type signature
24
+ function check_supported_eltype (:: Type{T} , :: Type{U} ) where {T, U}
25
+ T === Symbol &&
26
+ throw (ArgumentError (" CategoricalArray no longer supports Symbol as element type " *
27
+ " as that forces recompiling too many Julia Base methods: " *
28
+ " use strings instead, e.g. via categorical(string.(x))" ))
29
+ T <: Union{SupportedTypes, Missing} ||
30
+ throw (ArgumentError (" CategoricalArray only supports " *
31
+ " AbstractString, AbstractChar and Number element types " *
32
+ " (got element type $U )" ))
33
+ end
34
+
22
35
fixstringtype (T:: Type ) = T <: SubString || T === AbstractString ? String : T
23
36
fixstringtype (T:: Union ) = Union{fixstringtype (T. a), fixstringtype (T. b)}
24
37
fixstringtype (:: Type{Union{}} ) = Union{}
25
38
39
+ # Find a narrow type that is supported to hold all elements if possible
40
+ function fixtype (A:: AbstractArray{T} ) where T
41
+ if T <: Union{SupportedTypes, Missing}
42
+ return fixstringtype (T)
43
+ else
44
+ U = fixstringtype (mapreduce (typeof, Base. promote_typejoin, A))
45
+ check_supported_eltype (U, T)
46
+ return U
47
+ end
48
+ end
49
+
26
50
"""
27
51
CategoricalArray{T}(undef, dims::Dims; levels=nothing, ordered=false)
28
52
CategoricalArray{T}(undef, dims::Int...; levels=nothing, ordered=false)
@@ -135,6 +159,7 @@ function CategoricalArray{T, N, R}(::UndefInitializer, dims::NTuple{N,Int};
135
159
ordered:: Bool = false ) where {T, N, R}
136
160
U = leveltype (nonmissingtype (T))
137
161
S = T >: Missing ? Union{U, Missing} : U
162
+ check_supported_eltype (S, T)
138
163
V = CategoricalValue{U, R}
139
164
levs = levels === nothing ? U[] : collect (U, levels)
140
165
CategoricalArray {S, N} (zeros (R, dims), CategoricalPool {U, R, V} (levs, ordered))
230
255
231
256
# From AbstractArray
232
257
233
- # Find a narrow type that is supported to hold all elements if possible
234
- function fixtype (A:: AbstractArray{T} ) where T
235
- U = T <: Union{SupportedTypes, Missing} ?
236
- T : mapreduce (typeof, Base. promote_typejoin, A)
237
- return fixstringtype (U)
238
- end
239
-
240
258
CategoricalArray {T, N} (A:: AbstractArray{S, N} ;
241
259
levels:: Union{AbstractVector, Nothing} = nothing ,
242
260
ordered:: Bool = _isordered (A)) where {S, T, N} =
@@ -319,6 +337,8 @@ convert(::Type{CategoricalArray{T, N, R}}, A::AbstractArray{S, N}) where {S, T,
319
337
320
338
function _convert (:: Type{CategoricalArray{T, N, R}} , A:: AbstractArray{S, N} ;
321
339
levels:: Union{AbstractVector, Nothing} = nothing ) where {S, T, N, R}
340
+ check_supported_eltype (T, T)
341
+
322
342
res = CategoricalArray {T, N, R} (undef, size (A), levels= levels)
323
343
copyto! (res, A)
324
344
0 commit comments