diff --git a/REQUIRE b/REQUIRE index 45033ed9..d77f5816 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,5 +1,5 @@ julia 0.6 Missings Reexport -Compat 0.61.0 +Compat 0.67.0 JSON diff --git a/src/array.jl b/src/array.jl index 8a57b859..6bdd7083 100644 --- a/src/array.jl +++ b/src/array.jl @@ -410,7 +410,7 @@ function copyto!(dest::CatArrOrSub{T, N}, dstart::Integer, n::Integer) where {T, N} n == 0 && return dest n < 0 && throw(ArgumentError(string("tried to copy n=", n, " elements, but n should be nonnegative"))) - destinds, srcinds = linearindices(dest), linearindices(src) + destinds, srcinds = LinearIndices(dest), LinearIndices(src) (dstart ∈ destinds && dstart+n-1 ∈ destinds) || throw(BoundsError(dest, dstart:dstart+n-1)) (sstart ∈ srcinds && sstart+n-1 ∈ srcinds) || throw(BoundsError(src, sstart:sstart+n-1)) @@ -526,8 +526,8 @@ function vcat(A::CategoricalArray...) newlevels, ordered = mergelevels(ordered, map(levels, A)...) refsvec = map(A) do a - ii = indexin(index(a.pool), newlevels) - [x==0 ? 0 : ii[x] for x in a.refs] + ii = convert(Vector{Int}, indexin(index(a.pool), newlevels)) + [x==0 ? 0 : ii[x] for x in a.refs]::Array{Int,ndims(a)} end T = Base.promote_eltype(A...) >: Missing ? @@ -609,7 +609,7 @@ function levels!(A::CategoricalArray{T}, newlevels::Vector; allow_missing=false) levelsmap = similar(A.refs, length(oldindex)+1) # 0 maps to a missing value levelsmap[1] = 0 - levelsmap[2:end] .= coalesce.(indexin(oldindex, index(A.pool)), 0) + levelsmap[2:end] .= something.(indexin(oldindex, index(A.pool)), 0) @inbounds for (i, x) in enumerate(A.refs) A.refs[i] = levelsmap[x+1] diff --git a/src/extras.jl b/src/extras.jl index 227e259c..d26ef91a 100644 --- a/src/extras.jl +++ b/src/extras.jl @@ -91,8 +91,13 @@ function cut(x::AbstractArray{T, N}, breaks::AbstractVector; n = length(breaks) if isempty(labels) - from = map(x -> sprint(showcompact, x), breaks[1:n-1]) - to = map(x -> sprint(showcompact, x), breaks[2:n]) + @static if VERSION >= v"0.7.0-DEV.4524" + from = map(x -> sprint(show, x, context=:compact=>true), breaks[1:n-1]) + to = map(x -> sprint(show, x, context=:compact=>true), breaks[2:n]) + else + from = map(x -> sprint(showcompact, x), breaks[1:n-1]) + to = map(x -> sprint(showcompact, x), breaks[2:n]) + end levs = Vector{String}(undef, n-1) for i in 1:n-2 levs[i] = string("[", from[i], ", ", to[i], ")") diff --git a/src/recode.jl b/src/recode.jl index 9ac87d9c..721dfcf9 100644 --- a/src/recode.jl +++ b/src/recode.jl @@ -337,7 +337,7 @@ function recode(a::AbstractArray, default::Any, pairs::Pair...) # assume the caller wants to recode only some values to missing, # but accept original values if T === Missing && !isa(default, Missing) - dest = Array{Union{eltype(a), Missing}}(size(a)) + dest = Array{Union{eltype(a), Missing}}(undef, size(a)) # Exception 2: if original array accepted missing values and missing does not appear # in one of the pairs' LHS, result must accept missing values elseif T >: Missing || default isa Missing || (eltype(a) >: Missing && !keytype_hasmissing(pairs...)) diff --git a/test/12_missingarray.jl b/test/12_missingarray.jl index fa27c447..3602a603 100644 --- a/test/12_missingarray.jl +++ b/test/12_missingarray.jl @@ -1034,7 +1034,7 @@ end end @testset "vcat with all empty array" begin - ca1 = CategoricalArray(0) + ca1 = CategoricalArray(undef, 0) ca2 = CategoricalArray([missing, "b"]) r = vcat(ca1, ca2) @test r ≅ [missing, "b"] @@ -1043,7 +1043,7 @@ end end @testset "vcat with all missings and empty" begin - ca1 = CategoricalArray(0) + ca1 = CategoricalArray(undef, 0) ca2 = CategoricalArray([missing, missing]) r = vcat(ca1, ca2) @test r ≅ [missing, missing] @@ -1056,7 +1056,7 @@ end @test isordered(r) ca1 = CategoricalArray(["a", missing]) - ca2 = CategoricalArray{Union{String, Missing}}(2) + ca2 = CategoricalArray{Union{String, Missing}}(undef, 2) ordered!(ca1, true) @test isempty(levels(ca2)) r = vcat(ca1, ca2) diff --git a/test/13_arraycommon.jl b/test/13_arraycommon.jl index 89a594ff..68f8152f 100644 --- a/test/13_arraycommon.jl +++ b/test/13_arraycommon.jl @@ -270,7 +270,7 @@ end @testset "copy src not supporting missings into dest not supporting missings" begin v = ["a", "b", "c"] src = levels!(CategoricalVector(v), reverse(v)) - dest = CategoricalVector{String}(3) + dest = CategoricalVector{String}(undef, 3) copyf!(dest, src) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -279,7 +279,7 @@ end @testset "copy src supporting missings into dest not supporting missings" begin v = ["a", "b", "c"] src = levels!(CategoricalVector{Union{Missing, String}}(v), reverse(v)) - dest = CategoricalVector{String}(3) + dest = CategoricalVector{String}(undef, 3) copyf!(dest, src) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -288,7 +288,7 @@ end @testset "copy src not supporting missings into dest supporting missings" begin v = ["a", "b", "c"] src = levels!(CategoricalVector(v), reverse(v)) - dest = CategoricalVector{Union{String, Missing}}(3) + dest = CategoricalVector{Union{String, Missing}}(undef, 3) copyf!(dest, src) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -297,7 +297,7 @@ end @testset "copy src supporting missings into dest supporting missings" begin v = ["a", "b", "c"] src = levels!(CategoricalVector{Union{String, Missing}}(v), reverse(v)) - dest = CategoricalVector{Union{String, Missing}}(3) + dest = CategoricalVector{Union{String, Missing}}(undef, 3) copyf!(dest, src) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -307,7 +307,7 @@ end v = ["a", "b", "c"] src = levels!(CategoricalVector(v), reverse(v)) vsrc = view(src, 1:length(src)) - dest = CategoricalVector{String}(3) + dest = CategoricalVector{String}(undef, 3) copyf!(dest, vsrc) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -317,7 +317,7 @@ end v = ["a", "b", "c"] src = levels!(CategoricalVector{Union{String, Missing}}(v), reverse(v)) vsrc = view(src, 1:length(src)) - dest = CategoricalVector{String}(3) + dest = CategoricalVector{String}(undef, 3) copyf!(dest, vsrc) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -327,7 +327,7 @@ end v = ["a", "b", "c"] src = levels!(CategoricalVector(v), reverse(v)) vsrc = view(src, 1:length(src)) - dest = CategoricalVector{Union{String, Missing}}(3) + dest = CategoricalVector{Union{String, Missing}}(undef, 3) copyf!(dest, vsrc) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -337,7 +337,7 @@ end v = ["a", "b", "c"] src = levels!(CategoricalVector{Union{String, Missing}}(v), reverse(v)) vsrc = view(src, 1:length(src)) - dest = CategoricalVector{Union{String, Missing}}(3) + dest = CategoricalVector{Union{String, Missing}}(undef, 3) copyf!(dest, vsrc) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -347,13 +347,13 @@ end v = ["a", "b", "c"] src = levels!(CategoricalVector(v), reverse(v)) vsrc = view(src, 1:2) - dest = CategoricalVector{String}(3) + dest = CategoricalVector{String}(undef, 3) copyf!(dest, vsrc) @test dest[1:2] == src[1:2] @test levels(dest) == levels(src) vsrc = view(src, 1:2) - dest = CategoricalVector{String}(2) + dest = CategoricalVector{String}(undef, 2) copyf!(dest, vsrc) @test dest == src[1:2] @test levels(dest) == levels(src) @@ -401,7 +401,7 @@ end v = ["a", "b", "c"] src = CategoricalVector{Union{eltype(v), Missing}}(v) levels!(src, reverse(v)) - dest = CategoricalVector{String}(3) + dest = CategoricalVector{String}(undef, 3) copyf!(dest, src) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -413,14 +413,14 @@ end src = CategoricalVector{AbstractString}(v) levels!(src, reverse(v)) - dest = CategoricalVector{String}(3) + dest = CategoricalVector{String}(undef, 3) copyf!(dest, src) @test dest == src @test levels(dest) == levels(src) == reverse(v) src = CategoricalVector{String}(v) levels!(src, reverse(v)) - dest = CategoricalVector{AbstractString}(3) + dest = CategoricalVector{AbstractString}(undef, 3) copyf!(dest, src) @test dest == src @test levels(dest) == levels(src) == reverse(v) @@ -429,7 +429,7 @@ end @testset "inviable mixed src and dest types" begin v = ["a", "b", missing] src = CategoricalVector(v) - dest = CategoricalVector{String}(3) + dest = CategoricalVector{String}(undef, 3) @test_throws MissingException copyf!(dest, src) vsrc = view(src, 1:length(src)) @@ -437,7 +437,7 @@ end v = Integer[-1, -2, -3] src = CategoricalVector(v) - dest = CategoricalVector{UInt}(3) + dest = CategoricalVector{UInt}(undef, 3) @test_throws InexactError copyf!(dest, src) end end @@ -532,7 +532,7 @@ end @test x2 == x end - fill!(x2, :c) + fill!(x2, "c") @test x2 == ["c", "c", "c"] @test levels(x2) == ["a", "b", "c"] @@ -727,7 +727,7 @@ end end @testset "converting from array with missings to array without missings CategoricalArray fails with missings" begin - x = CategoricalArray{Union{String, Missing}}(1) + x = CategoricalArray{Union{String, Missing}}(undef, 1) @test_throws MissingException CategoricalArray{String}(x) @test_throws MissingException convert(CategoricalArray{String}, x) end @@ -808,8 +808,8 @@ end @testset "vcat() takes into account element type even when array is empty" begin # or when both arrays have the same levels but of different types - x = CategoricalVector{String}(0) - y = CategoricalVector{Int}(0) + x = CategoricalVector{String}(undef, 0) + y = CategoricalVector{Int}(undef, 0) z1 = CategoricalVector{Float64}([1.0]) z2 = CategoricalVector{Int}([1]) @inferred vcat(x, y) diff --git a/test/16_recode.jl b/test/16_recode.jl index d99ab336..964d8a72 100644 --- a/test/16_recode.jl +++ b/test/16_recode.jl @@ -14,7 +14,8 @@ const ≅ = isequal @testset "Recoding from $(typeof(x)) to $(typeof(y))" for x in ([1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)), y in (similar(x), Array{Int}(undef, size(x)), - CategoricalArray{Int}(size(x)), CategoricalArray{Union{Int, Missing}}(size(x)), x) + CategoricalArray{Int}(undef, size(x)), + CategoricalArray{Union{Int, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, 1=>100, 2:4=>0, [5; 9:10]=>-1) @test y === z @@ -28,7 +29,8 @@ end @testset "Recoding from $(typeof(x)) to $(typeof(y)) with duplicate recoded values" for x in ([1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)), y in (similar(x), Array{Int}(undef, size(x)), - CategoricalArray{Int}(size(x)), CategoricalArray{Union{Int, Missing}}(size(x)), x) + CategoricalArray{Int}(undef, size(x)), + CategoricalArray{Union{Int, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, 1=>100, 2:4=>100, [5; 9:10]=>-1) @test y === z @@ -42,7 +44,8 @@ end @testset "Recoding from $(typeof(x)) to $(typeof(y)) with unused level" for x in ([1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)), y in (similar(x), Array{Int}(undef, size(x)), - CategoricalArray{Int}(size(x)), CategoricalArray{Union{Int, Missing}}(size(x)), x) + CategoricalArray{Int}(undef, size(x)), + CategoricalArray{Union{Int, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, 1=>100, 2:4=>0, [5; 9:10]=>-1, 100=>1) @test y === z @@ -56,7 +59,8 @@ end @testset "Recoding from $(typeof(x)) to $(typeof(y)) with duplicate default" for x in ([1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)), y in (similar(x), Array{Int}(undef, size(x)), - CategoricalArray{Int}(size(x)), CategoricalArray{Union{Int, Missing}}(size(x)), x) + CategoricalArray{Int}(undef, size(x)), + CategoricalArray{Union{Int, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, 100, 1=>100, 2:4=>100, [5; 9:10]=>-1) @test y === z @@ -70,7 +74,8 @@ end @testset "Recoding from $(typeof(x)) to $(typeof(y)) with default" for x in ([1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)), y in (similar(x), Array{Int}(undef, size(x)), - CategoricalArray{Int}(size(x)), CategoricalArray{Union{Int, Missing}}(size(x)), x) + CategoricalArray{Int}(undef, size(x)), + CategoricalArray{Union{Int, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, -10, 1=>100, 2:4=>0, [5; 9:10]=>-1) @test y === z @@ -84,7 +89,8 @@ end @testset "Recoding from $(typeof(x)) to $(typeof(y)) with first value being Float64" for x in ([1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)), y in (similar(x), Array{Int}(undef, size(x)), - CategoricalArray{Int}(size(x)), CategoricalArray{Union{Int, Missing}}(size(x)), x) + CategoricalArray{Int}(undef, size(x)), + CategoricalArray{Union{Int, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, 1.0=>100, 2:4=>0, [5; 9:10]=>-1) @test y == [100, 0, 0, 0, -1, 6, 7, 8, -1, -1] @@ -97,7 +103,8 @@ end @testset "Recoding from $(typeof(x)) to $(typeof(y)) with overlapping pairs" for x in ([1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)), y in (similar(x), Array{Int}(undef, size(x)), - CategoricalArray{Int}(size(x)), CategoricalArray{Union{Int, Missing}}(size(x)), x) + CategoricalArray{Int}(undef, size(x)), + CategoricalArray{Union{Int, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, 1=>100, 2:4=>0, [5; 9:10]=>-1, 1:10=>0) @test y === z @@ -111,7 +118,8 @@ end @testset "Recoding from $(typeof(x)) to $(typeof(y)) with changes to levels order" for x in ([1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)), y in (similar(x), Array{Int}(undef, size(x)), - CategoricalArray{Int}(size(x)), CategoricalArray{Union{Int, Missing}}(size(x)), x) + CategoricalArray{Int}(undef, size(x)), + CategoricalArray{Union{Int, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, 1=>100, 2:4=>0, [5; 9:10]=>-1) @test y === z @@ -129,14 +137,14 @@ end y = Vector{String}(undef, 4) @test_throws MissingException recode!(y, x, "a", "c"=>"b") - y = CategoricalVector{String}(4) + y = CategoricalVector{String}(undef, 4) @test_throws MissingException recode!(y, x, "a", "c"=>"b") end @testset "Recoding array with missings and default from $(typeof(x)) to $(typeof(y))" for x in (["a", missing, "c", "d"], CategoricalArray(["a", missing, "c", "d"])), - y in (similar(x), Array{Union{String, Missing}}(size(x)), - CategoricalArray{Union{String, Missing}}(size(x)), x) + y in (similar(x), Array{Union{String, Missing}}(undef, size(x)), + CategoricalArray{Union{String, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, "a", "c"=>"b") @test y === z @@ -149,8 +157,8 @@ end @testset "Recoding array with missings and no default from $(typeof(x)) to $(typeof(y))" for x in (["a", missing, "c", "d"], CategoricalArray(["a", missing, "c", "d"])), - y in (similar(x), Array{Union{String, Missing}}(size(x)), - CategoricalArray{Union{String, Missing}}(size(x)), x) + y in (similar(x), Array{Union{String, Missing}}(undef, size(x)), + CategoricalArray{Union{String, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, "c"=>"b") @test y === z @@ -163,8 +171,8 @@ end @testset "Collection in LHS recoding array with missings and no default from $(typeof(x)) to $(typeof(y))" for x in (["1", missing, "3", "4", "5"], CategoricalArray(["1", missing, "3", "4", "5"])), - y in (similar(x), Array{Union{String, Missing}}(size(x)), - CategoricalArray{Union{String, Missing}}(size(x)), x) + y in (similar(x), Array{Union{String, Missing}}(undef, size(x)), + CategoricalArray{Union{String, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, ["3","4"]=>"2") @test y === z @@ -177,8 +185,8 @@ end @testset "Recoding array with missings, default and with missing as a key pair from $(typeof(x)) to $(typeof(y))" for x in (["a", missing, "c", "d"], CategoricalArray(["a", missing, "c", "d"])), - y in (similar(x), Array{Union{String, Missing}}(size(x)), - CategoricalArray{Union{String, Missing}}(size(x)), x) + y in (similar(x), Array{Union{String, Missing}}(undef, size(x)), + CategoricalArray{Union{String, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, "a", "c"=>"b", missing=>"d") @test y === z @@ -191,8 +199,8 @@ end @testset "Collection with missing in LHS recoding array with missings, default from $(typeof(x)) to $(typeof(y))" for x in (["a", missing, "c", "d"], CategoricalArray(["a", missing, "c", "d"])), - y in (similar(x), Array{Union{String, Missing}}(size(x)), - CategoricalArray{Union{String, Missing}}(size(x)), x) + y in (similar(x), Array{Union{String, Missing}}(undef, size(x)), + CategoricalArray{Union{String, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, "a", [missing, "c"]=>"b") @test y === z @@ -205,8 +213,8 @@ end @testset "Recoding array with missings, no default and with missing as a key pair from $(typeof(x)) to $(typeof(y))" for x in (["a", missing, "c", "d"], CategoricalArray(["a", missing, "c", "d"])), - y in (similar(x), Array{Union{String, Missing}}(size(x)), - CategoricalArray{Union{String, Missing}}(size(x)), x) + y in (similar(x), Array{Union{String, Missing}}(undef, size(x)), + CategoricalArray{Union{String, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, "c"=>"b", missing=>"d") @test y === z @@ -219,8 +227,8 @@ end @testset "Collection with missing in LHS recoding array with missings, no default from $(typeof(x)) to $(typeof(y))" for x in (["a", missing, "c", "d"], CategoricalArray(["a", missing, "c", "d"])), - y in (similar(x), Array{Union{String, Missing}}(size(x)), - CategoricalArray{Union{String, Missing}}(size(x)), x) + y in (similar(x), Array{Union{String, Missing}}(undef, size(x)), + CategoricalArray{Union{String, Missing}}(undef, size(x)), x) z = @inferred recode!(y, x, ["c", missing]=>"b") @test y === z @@ -233,22 +241,24 @@ end @testset "Recoding into an array of incompatible size from $(typeof(x)) to $(typeof(y))" for x in (["a", missing, "c", "d"], CategoricalArray(["a", missing, "c", "d"])), - y in (similar(x, 0), Array{Union{String, Missing}}(0), - CategoricalArray{Union{String, Missing}}(0)) + y in (similar(x, 0), Array{Union{String, Missing}}(undef, 0), + CategoricalArray{Union{String, Missing}}(undef, 0)) @test_throws DimensionMismatch recode!(y, x, "c"=>"b", missing=>"d") end @testset "Recoding into an array with incompatible eltype from $(typeof(x)) to $(typeof(y))" for x in ([1:10;], CategoricalArray(1:10)), - y in (similar(x, String), Array{String}(undef, size(x)), CategoricalArray{String}(size(x))) + y in (similar(x, String), Array{String}(undef, size(x)), + CategoricalArray{String}(undef, size(x))) @test_throws ArgumentError recode!(y, x, 1=>"a", 2:4=>"b", [5; 9:10]=>"c") end @testset "Recoding into an array with incompatible eltype from $(typeof(x)) to $(typeof(y))" for x in ((Union{Int, Missing})[1:10;], CategoricalArray{Union{Int, Missing}}(1:10)), - y in (similar(x), Array{Union{Int, Missing}}(size(x)), CategoricalArray{Union{Int, Missing}}(size(x))) + y in (similar(x), Array{Union{Int, Missing}}(undef, size(x)), + CategoricalArray{Union{Int, Missing}}(undef, size(x))) @test_throws MethodError recode!(y, x, 1=>"a", 2:4=>"b", [5; 9:10]=>"c") end @@ -279,7 +289,8 @@ end end end -@testset "recode() promotion for $(typeof(x))" for x in (1:10, [1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)) +@testset "recode() promotion for $(typeof(x))" for + x in (1:10, [1:10;], CategoricalArray(1:10), CategoricalArray{Union{Int, Missing}}(1:10)) T = eltype(x) >: Missing ? Missing : Union{} # Recoding from Int to Float64 due to a second value being Float64