Missing Values and nothing
Prerequisites: Statistics and random numbers
Julia has two different "empty" values:
nothing(typeNothing) means no value — a function that doesn't return anything, or a search that found nothing.missing(typeMissing) means a value exists but we don't know it — a blank cell in a data table, as in statistics and SQL.
println(typeof(missing), " ", typeof(nothing))
println(missing + 1, " ", missing > 3, " ", missing == missing)
println(ismissing(missing), " ", isnothing(nothing))
println(true || missing, " ", false && missing)
try
nothing + 1
catch err
println(typeof(err))
end
Missing Nothing
missing missing missing
true true
true false
MethodError
missing propagates: any arithmetic or comparison with it gives
missing, because the true answer is unknown. nothing doesn't — using
it in arithmetic is an error.
Working with missing data
using Statistics
heights = [172, missing, 168, 181, missing]
println(eltype(heights))
println(mean(heights))
println(mean(skipmissing(heights)))
println(count(ismissing, heights))
println(coalesce.(heights, 0))
println(collect(skipmissing(heights)))
Union{Missing, Int64}
missing
173.66666666666666
2
[172, 0, 168, 181, 0]
[172, 168, 181]
- A vector with missing values has type
Vector{Union{Missing, Int64}}— and it's still fast. skipmissingiterates over the non-missing values.coalesce(x, default)replacesmissingwith a default.
Comparing safely
x = missing
try
if x > 3
println("big")
end
catch err
println(typeof(err))
end
println(isequal(missing, missing), " ", coalesce(x > 3, false))
TypeError
true false
if needs a real Bool, so decide what missing should mean before
testing. isequal treats two missings as equal (it's what Dict and
sorting use).
nothing and something
config = Dict("port" => "8080")
port = something(tryparse(Int, get(config, "port", "")), 3000)
timeout = something(tryparse(Int, get(config, "timeout", "")), 30)
println(port, " ", timeout)
8080 30
something(a, b, ...) returns the first argument that isn't nothing —
handy for defaults.