JKHA
JKHA

Reputation: 1896

Define a custom sortperm function

In Julia, let's suppose I have the following matrix:

julia> rank = [[1.0,2.0,NaN] [5.0,3.0,1.0]]
3×2 Array{Float64,2}:
   1.0  5.0
   2.0  3.0
 NaN    1.0

Using mapslices and sortperm to get a ranking on each column gives:

 r = mapslices(sortperm, rank; dims=1)
3×2 Array{Int64,2}:
 1  3
 2  2
 3  1

The problem being that NaN are considered as "worst" elements instead of being kept in final matrix. What I finally want is:

3×2 Array{Int64,2}:
 1  3
 2  2
 NaN  1

My current workaround is to compare each element of r with those of rank. But I'm quite sure Julia has a classier way of doing it :p.

Current workaround: not enough because requires extra computation after mapslices as well as creating another array new_r.

nrow, ncol = size(r)
new_r = [Float64(ifelse(isnan(rank[i,j]), NaN, r[i,j])) for i in 1:nrow, j in 1:ncol]

Upvotes: 2

Views: 239

Answers (1)

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69949

NaN is not "special" in Julia. It is just a floating point value. If you want NaN to be treated as missing value you should first convert it to missing and then use ordinalrank function from StatsBase.jl:

julia> rank = [[1.0,2.0,NaN] [5.0,3.0,1.0]]
3×2 Array{Float64,2}:
   1.0  5.0
   2.0  3.0
 NaN    1.0

julia> using StatsBase

julia> mapslices(rank; dims=1) do x
           ordinalrank(replace(x, NaN=>missing))
       end
3×2 Array{Union{Missing, Int64},2}:
 1         3
 2         2
  missing  1

Upvotes: 3

Related Questions