Skip to content

Commit

Permalink
iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
PharmCat committed Aug 9, 2021
1 parent 16c48d9 commit 566100d
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 3 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# MetidaBase.jl


[![Tier 1](https://github.com/PharmCat/MetidaBase.jl/actions/workflows/Tier1.yml/badge.svg)](https://github.com/PharmCat/MetidaBase.jl/actions/workflows/Tier1.yml)

[![codecov](https://codecov.io/gh/PharmCat/MetidaBase.jl/branch/main/graph/badge.svg?token=C6D0R654F9)](https://codecov.io/gh/PharmCat/MetidaBase.jl)


Metida base package.

Used for:
Expand Down
3 changes: 2 additions & 1 deletion src/MetidaBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ module MetidaBase
import StatsModels: StatisticalModel
import Tables: istable, columnaccess, columns, getcolumn, columnnames

import Base: getindex, length, ht_keyindex, show, pushfirst!, iterate
import Base: getindex, length, ht_keyindex, show, pushfirst!, iterate, size

include("abstracttype.jl")
include("types.jl")
include("utils.jl")
include("iterators.jl")

end
69 changes: 69 additions & 0 deletions src/iterators.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
################################################################################
struct SkipNonPositive{T}
x::T
end
skipnonpositive(itr) = SkipNonPositive(itr)

Base.IteratorEltype(::Type{SkipNonPositive{T}}) where {T} = Base.IteratorEltype(T)
#Base.eltype(::Type{SkipNonPositive{T}}) where {T} = nonmissingtype(eltype(T))
function Base.iterate(itr::SkipNonPositive, state...)
y = iterate(itr.x, state...)
y === nothing && return nothing
item, state = y
while !ispositive(item)
y = iterate(itr.x, state)
y === nothing && return nothing
item, state = y
end
item, state
end
Base.IndexStyle(::Type{<:SkipNonPositive{T}}) where {T} = IndexStyle(T)
Base.eachindex(itr::SkipNonPositive) =
Iterators.filter(i -> ispositive(@inbounds(itr.x[i])), eachindex(itr.x))
Base.keys(itr::SkipNonPositive) =
Iterators.filter(i -> ispositive(@inbounds(itr.x[i])), keys(itr.x))
Base.@propagate_inbounds function getindex(itr::SkipNonPositive, I...)
v = itr.x[I...]
!ispositive(v) && throw(ErrorException("the value at index $I is non positive"))
v
end
function Base.length(itr::SkipNonPositive)
n = 0
for i in itr n+=1 end
n
end
################################################################################
struct SkipNaNorMissing{T}
x::T
end
skipnanormissing(itr) = SkipNaNorMissing(itr)

Base.IteratorEltype(::Type{SkipNaNorMissing{T}}) where {T} = Base.IteratorEltype(T)
#Base.eltype(::Type{SkipNaNorMissing{T}}) where {T} = nonmissingtype(eltype(T))
function Base.iterate(itr::SkipNaNorMissing, state...)
y = iterate(itr.x, state...)
y === nothing && return nothing
item, state = y
while isnanormissing(item)
y = iterate(itr.x, state)
y === nothing && return nothing
item, state = y
end
item, state
end
Base.IndexStyle(::Type{<:SkipNaNorMissing{T}}) where {T} = IndexStyle(T)
Base.eachindex(itr::SkipNaNorMissing) =
Iterators.filter(i -> isnanormissing(@inbounds(itr.x[i])), eachindex(itr.x))
Base.keys(itr::SkipNaNorMissing) =
Iterators.filter(i -> isnanormissing(@inbounds(itr.x[i])), keys(itr.x))
Base.@propagate_inbounds function getindex(itr::SkipNaNorMissing, I...)
v = itr.x[I...]
!isnanormissing(v) && throw(ErrorException("The value at index $I is NaN or missing!"))
v
end
function Base.length(itr::SkipNaNorMissing)
n = 0
for i in itr n+=1 end
n
end
################################################################################
10 changes: 10 additions & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ function Base.pushfirst!(t::MetidaTable, row::NamedTuple)
t
end

function Base.size(t::MetidaTable, i::Int)
if i == 1
return length(t.table[1])
elseif i == 2
return length(t.table)
else
error("Wrong dimention!")
end
end

function Base.show(io::IO, table::MetidaTable)
pretty_table(io, table; tf = PrettyTables.tf_compact)
end
Expand Down
10 changes: 10 additions & 0 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,19 @@ function sortbyvec!(a, vec)
sort!(a, by = x -> findfirst(y -> x == y, vec))
end

################################################################################
################################################################################

isnanormissing(x::Number) = isnan(x)
isnanormissing(x::AbstractFloat) = isnan(x)
isnanormissing(x::Missing) = true

ispositive(::Missing) = false
ispositive(x::AbstractFloat) = isnan(x) ? false : x > zero(x)
ispositive(x) = x > zero(x)

################################################################################
################################################################################

# STATISTICS

Expand Down
18 changes: 16 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ using Test
mt[:, :b]
Base.show(io, mt)

@test size(mt, 1) == 5
@test size(mt, 2) == 2

struct ExampleIDStruct <: MetidaBase.AbstractSubject
#time
#obs
Expand Down Expand Up @@ -51,19 +54,30 @@ using Test
@test exrsds[:, :r1][1] == 3
@test exrsds[1, :r1] == 3


@test MetidaBase.getid(exidds[3], :a) == 2
sort!(exidds, :a)
@test MetidaBase.getid(exidds[3], :a) == 3
MetidaBase.getid(exrsds, :, :a)

sort!(exrsds, :a)

@test first(exrsds) == exrsds[1]

MetidaBase.uniqueidlist(exidds, [:a])
MetidaBase.uniqueidlist(exidds, :a)

MetidaBase.subset(exidds, Dict(:a => 1))
#println(exrsds[:, :r1])

#println(MetidaBase.getid(exrsds, :, :a1))
mt = MetidaBase.metida_table(exrsds)

v1 = [1,2,-6,missing,NaN]
itr1 = MetidaBase.skipnanormissing(v1)
for i in itr1
@test !MetidaBase.isnanormissing(i)
end
itr2 = MetidaBase.skipnonpositive(v1)
for i in itr2
@test MetidaBase.ispositive(i)
end
end

0 comments on commit 566100d

Please sign in to comment.