contingency table for Julia array

Viewed 94

Consider a (m x n) matrix of only 0s and 1s, with m potentially large.

julia> rand([0, 1], 5, 3)
5×3 Array{Int64,2}:
 0  1  1
 0  0  0
 0  1  1
 1  0  0
 1  0  1

Is there an efficient way to count the number of occurrences and track the indices for each unique row?

For example, the first row above occurs twice, at indices 1 and 3. I am trying to build a sort of contingency table.

Thanks

1 Answers

This is one of the approaches that is based only on functionalities provided in Julia Base:

julia> x = rand([0, 1], 20, 3)
20×3 Matrix{Int64}:
 1  0  1
 1  1  1
 0  0  0
 1  0  0
 0  0  1
 1  0  1
 0  0  0
 1  0  1
 0  0  0
 0  0  1
 1  1  0
 0  1  1
 0  1  1
 1  0  0
 0  0  0
 0  0  0
 0  0  1
 0  1  0
 1  1  0
 1  0  0

julia> d = Dict()
Dict{Any, Any}()

julia> for (i, r) in enumerate(eachrow(x))
           push!(get!(d, r, Int[]), i)
       end

julia> d
Dict{Any, Any} with 8 entries:
  [1, 1, 1] => [2]
  [0, 0, 0] => [3, 7, 9, 15, 16]
  [0, 0, 1] => [5, 10, 17]
  [1, 1, 0] => [11, 19]
  [1, 0, 0] => [4, 14, 20]
  [0, 1, 1] => [12, 13]
  [1, 0, 1] => [1, 6, 8]
  [0, 1, 0] => [18]

and now using the SplitApplyCombine.jl package:

julia> using SplitApplyCombine

julia> group(i -> view(x, i, :), axes(x, 1))
8-element Dictionaries.Dictionary{Any, Vector{Int64}}
 [1, 0, 1] │ [1, 6, 8]
 [1, 1, 1] │ [2]
 [0, 0, 0] │ [3, 7, 9, 15, 16]
 [1, 0, 0] │ [4, 14, 20]
 [0, 0, 1] │ [5, 10, 17]
 [1, 1, 0] │ [11, 19]
 [0, 1, 1] │ [12, 13]
 [0, 1, 0] │ [18]
Related