Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.jl.cov
*.jl.*.cov
*.jl.mem
Manifest.toml
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
[compat]
julia = "1"
DataAPI = "1.1"
Documenter = "0.27, 1"

[extras]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "SparseArrays"]
test = ["Test", "Documenter", "SparseArrays"]
56 changes: 28 additions & 28 deletions src/Missings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ See also: [`skipmissing`](@ref), [`Missings.fail`](@ref)
# Examples
```jldoctest
julia> collect(Missings.replace([1, missing, 2], 0))
3-element Array{Int64,1}:
3-element Vector{$Int}:
1
0
2

julia> collect(Missings.replace([1 missing; 2 missing], 0))
2×2 Array{Int64,2}:
2×2 Matrix{$Int}:
1 0
2 0

Expand Down Expand Up @@ -129,7 +129,7 @@ See also: [`skipmissing`](@ref), [`Missings.replace`](@ref)
# Examples
```jldoctest
julia> collect(Missings.fail([1 2; 3 4]))
2×2 Array{Int64,2}:
2×2 Matrix{$Int}:
1 2
3 4

Expand Down Expand Up @@ -216,9 +216,9 @@ julia> passmissing(sqrt)(missing)
missing

julia> passmissing(sqrt).([missing, 4])
2-element Array{Union{Missing, Float64},1}:
2-element Vector{Union{Missing, Float64}}:
missing
2.0
2.0

julia> passmissing((x,y)->"\$x \$y")(1, 2)
"1 2"
Expand All @@ -237,17 +237,19 @@ skipping elements at positions where at least one of the iterators returns `miss
(listwise deletion of missing values).

# Examples
```
```julia-repl
julia> x = [1, 2, missing, 4]; y = [1, 2, 3, missing];

julia> tx, ty = skipmissings(x, y)
(Missings.SkipMissings{Array{Union{Missing, Int64},1},Tuple{Array{Union{Missing, Int64},1}}}
(Union{Missing, Int64}[1, 2, missing, 4], (Union{Missing, Int64}[1, 2, 3, missing],)), Missi
ngs.SkipMissings{Array{Union{Missing, Int64},1},Tuple{Array{Union{Missing, Int64},1}}}(Union
{Missing, Int64}[1, 2, 3, missing], (Union{Missing, Int64}[1, 2, missing, 4],)))
julia> tx, ty = skipmissings(x, y);

julia> tx
Missings.SkipMissings{Vector{Union{Missing, Int64}}}(Union{Missing, Int64}[1, 2, missing, 4]) comprised of 2 iterators

julia> ty
Missings.SkipMissings{Vector{Union{Missing, Int64}}}(Union{Missing, Int64}[1, 2, 3, missing]) comprised of 2 iterators

julia> collect(tx)
2-element Array{Int64,1}:
2-element Vector{Int64}:
1
2

Expand Down Expand Up @@ -281,7 +283,7 @@ struct SkipMissings{V, T}
others::T
end

Base.@propagate_inbounds function _anymissingindex(others::Tuple{Vararg{AbstractArray}}, i)
Base.@propagate_inbounds function _anymissingindex(others::Tuple{Vararg{AbstractArray}}, i)
for oth in others
oth[i] === missing && return true
end
Expand All @@ -301,7 +303,7 @@ end
const SkipMissingsofArrays = SkipMissings{V, T} where
{V <: AbstractArray, T <: Tuple{Vararg{AbstractArray}}}

function Base.show(io::IO, mime::MIME"text/plain", itr::SkipMissings{V}) where V
function Base.show(io::IO, mime::MIME"text/plain", itr::SkipMissings{V}) where V
print(io, SkipMissings, '{', V, '}', '(', itr.x, ')', " comprised of " *
"$(length(itr.others) + 1) iterators")
end
Expand Down Expand Up @@ -358,7 +360,7 @@ end
@inline function Base.getindex(itr::SkipMissingsofArrays, i)
@boundscheck checkbounds(itr.x, i)
@inbounds xi = itr.x[i]
if xi === missing || @inbounds _anymissingindex(itr.others, i)
if xi === missing || @inbounds _anymissingindex(itr.others, i)
throw(MissingException("the value at index $i is missing for some element"))
end
return xi
Expand Down Expand Up @@ -462,18 +464,16 @@ to `skipmissing` and elements for which `f` returns `false`. This method
only applies when all iterators passed to `skipmissings` are arrays.

# Examples
```
julia> x = [missing; 2:9]; y = [1:9; missing];
```julia-repl
julia> x = [missing; 2:9]; y = [2:9; missing];

julia> mx, my = skipmissings(x, y);

julia> filter(isodd, mx)
4-element Array{Int64,1}:
julia> filter(isodd, collect(mx))
3-element Vector{$Int}:
3
5
7
9

```
"""
function filter(f, itr::SkipMissingsofArrays)
Expand All @@ -497,7 +497,7 @@ and otherwise returns `f(x, args...; kwargs...)`, where `args` are following
positional arguments passed to `f` and `kwargs` are its keyword arguments.

# Examples
```
```jldoctest
julia> emptymissing(last)([])
missing

Expand All @@ -508,8 +508,8 @@ julia> emptymissing(first)([], 2)
missing

julia> emptymissing(first)([1], 2)
1-element Vector{Int64}:
1
1-element Vector{$Int}:
1
```
"""
emptymissing(f) = (x, args...; kwargs...) -> isempty(x) ? missing : f(x, args...; kwargs...)
Expand All @@ -523,7 +523,7 @@ end
missingsmallest(f)

Return a function of two arguments `x` and `y` that tests whether `x` is less
than `y` such that `missing` is always less than the other argument. In other
than `y` such that `missing` is always less than the other argument. In other
words, return a modified version of the partial order function `f` such that
`missing` is the smallest possible value, and all other non-`missing` values are
compared according to `f`.
Expand All @@ -533,7 +533,7 @@ the smallest value can be obtained by calling the 2-argument `missingsmallest(x,
y)` function. This is equivalent to `missingsmallest(isless)(x, y)`.

# Examples
```
```jldoctest
julia> isshorter = missingsmallest((s1, s2) -> isless(length(s1), length(s2)));

julia> isshorter("short", "longstring")
Expand Down Expand Up @@ -566,15 +566,15 @@ missing values appear at the end.
# Examples
```jldoctest
julia> sort(v, lt=missingsmallest)
5-element Vector{Union{Missing, Int64}}:
5-element Vector{Union{Missing, $Int}}:
missing
missing
1
2
10

julia> sort(v, lt=missingsmallest, rev=true)
5-element Vector{Union{Missing, Int64}}:
5-element Vector{Union{Missing, $Int}}:
10
2
1
Expand Down
68 changes: 36 additions & 32 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Test, SparseArrays, Missings
using Test, SparseArrays, Documenter, Missings

# Must be defined outside testset on v1.0
struct CubeRooter end
Expand Down Expand Up @@ -247,40 +247,44 @@ struct CubeRooter end
end
end

@testset "emptymissing" begin
@test emptymissing(last)([]) === missing
@test emptymissing(last)([1, 2, 3]) === 3
@test emptymissing(sum)(skipmissing(missings(Int, 3))) === missing
@test emptymissing(sum)(skipmissing([1, 2, 3])) === 6
fun(a, b; c) = (b, c)
@test emptymissing(fun)([], 1, c=2) === missing
@test emptymissing(fun)(3, 1, c=2) == (1, 2)
end
@testset "emptymissing" begin
@test emptymissing(last)([]) === missing
@test emptymissing(last)([1, 2, 3]) === 3
@test emptymissing(sum)(skipmissing(missings(Int, 3))) === missing
@test emptymissing(sum)(skipmissing([1, 2, 3])) === 6
fun(a, b; c) = (b, c)
@test emptymissing(fun)([], 1, c=2) === missing
@test emptymissing(fun)(3, 1, c=2) == (1, 2)
end

@testset "missingsmallest" begin
@test missingsmallest(missing, Inf) == true
@test missingsmallest(-Inf, missing) == false
@test missingsmallest(missing, missing) == false
@test missingsmallest(3, 4) == true
@test missingsmallest(-Inf, Inf) == true
@testset "missingsmallest" begin
@test missingsmallest(missing, Inf) == true
@test missingsmallest(-Inf, missing) == false
@test missingsmallest(missing, missing) == false
@test missingsmallest(3, 4) == true
@test missingsmallest(-Inf, Inf) == true

@test missingsmallest("a", "b") == true
@test missingsmallest("short", missing) == false
@test missingsmallest(missing, "") == true
@test missingsmallest("a", "b") == true
@test missingsmallest("short", missing) == false
@test missingsmallest(missing, "") == true

@test missingsmallest((1, 2), (3, 4)) == true
@test missingsmallest((3, 4), (1, 2)) == false
@test missingsmallest(missing, (1e3, 1e4)) == true

# Compare strings by length, not lexicographically
isshorter = missingsmallest((s1, s2) -> isless(length(s1), length(s2)))
@test isshorter("short", "longstring") == true
@test isshorter("longstring", "short") == false
@test isshorter(missing, "short") == true
@test isshorter("", missing) == false
@test missingsmallest((1, 2), (3, 4)) == true
@test missingsmallest((3, 4), (1, 2)) == false
@test missingsmallest(missing, (1e3, 1e4)) == true

@test_throws MethodError missingsmallest(isless)(isless)
@test missingsmallest !== missingsmallest(isless)
end
# Compare strings by length, not lexicographically
isshorter = missingsmallest((s1, s2) -> isless(length(s1), length(s2)))
@test isshorter("short", "longstring") == true
@test isshorter("longstring", "short") == false
@test isshorter(missing, "short") == true
@test isshorter("", missing) == false

@test_throws MethodError missingsmallest(isless)(isless)
@test missingsmallest !== missingsmallest(isless)
end

@static if VERSION >= v"1.6.0"
DocMeta.setdocmeta!(Missings, :DocTestSetup, :(using Missings))
doctest(Missings; manual = false)
end
end
Loading