# How to find rankings of each tuple in the list of tuples?

**URL:** <https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428>\
**Category:** General Usage\
**Tags:** question\
**Created:** [December 8, 2022, 2:44pm UTC](https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428 "2022-12-08T14:44:04Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Phuntsho](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phuntsho/32/46546_2.png) [@Phuntsho](https://discourse.julialang.org/u/Phuntsho)\
**Post date:** [December 8, 2022, 2:44pm UTC](https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428/1 "2022-12-08T14:44:04Z")

</div>

I have a list of tuples something like as shown:

```julia
v = [(i,rand(1:15)) for i=1:30]

```

Now I want to rank each tuple according to the second value, which I was able to achieve using many functions as shown.

```julia
vcat([map(k->(k[1],i),filter(x->x[2]==j,v)) for (i,j) in enumerate(sort(unique(last.(v))))]...)

```

Is there any simpler function that can give the same result? Thanks for your help as always.  
note following is not desired

```julia
sort(v, by x->x[2])

```

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [December 8, 2022, 4:45pm UTC](https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428/2 "2022-12-08T16:45:29Z")

</div>

Apologies but I don’t understand your question. “rank each tuple according to the second value” to me means (for a length-2 tuple) `sort(v, by = last)`.

Your longer expression constructs new tuples, and only returns the same tuples as in the original list around 1/9 of the time:

```julia
julia> function compare_sorts(n)
           res = 0
           for _ ∈ 1:n
               v = [(i,rand(1:15)) for i=1:30]
               sort1 = vcat([map(k->(k[1],i),filter(x->x[2]==j,v)) for (i,j) in enumerate(sort(unique(last.(v))))]...)
               sort2 = sort(v, by = last)
               res += sort1 == sort2
           end
           return res/n
       end
compare_sorts (generic function with 1 method)

julia> compare_sorts(10_000)
0.1108

```

with more samples this converges to 0.1111… so I’m sure it can be shown analytically that the expected value given your chosen example values of 30 tuples with random integers from 1:15.

The issue is `enumerate` which will create different `i` and `j` values at some point unless the second values of your 30 tuples include all consecutive numbers from 1 up. This being the Julia Discourse, there’s a good chance someone will be along shortly to show that the probability of this happening is indeed 1/9, peasants like me will just brute force it:

```julia
julia> z = [rand(1:15, 30) for _ ∈ 1:1_000_000];

julia> sum(count(length(unique(i)) == x && maximum(i) == x for i ∈ z) for x ∈ 11:15)/1_000_000
0.110809

```

Is this intended behaviour? If so your function is probably fine, I might have written it like that:

```julia
reduce(vcat, (k->(k[1],i)).(filter(x->x[2]==j,v)) for (i,j) in enumerate(sort(unique(last.(v)))))

```

I would have expected this to be faster, but for some reason in my benchmarking I see an extra 10 allocations and about 10% worse performance compared to your version so 🤷

---

<div class="post-metadata">

**Author:** ![Phuntsho](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phuntsho/32/46546_2.png) [@Phuntsho](https://discourse.julialang.org/u/Phuntsho)\
**Post date:** [December 8, 2022, 5:10pm UTC](https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428/3 "2022-12-08T17:10:57Z")

</div>

Thank you very much for your elaborate consideration. Yes, `sort(v, by = last)` sorts the tuple list based on the last value and it does rank elements but for my requirement instead of returning the original sorted `v `, I want to modify `v` such that ranking is done based on the positive integers. For instance, if I assume each tuple in `v` contains a student number corresponding to an exam score, (note more than one student can have the same exam score), now instead of ranking students based on their actual exam score, I want to rank them based on the position. i.e, whoever scores the lowest gets position 1, and so on. For example say `v=[(1,15),(2,13),(4,13), (5,6)]` should be `v=[(1,3),(2,2),(4,2),(5,1)]` hope my question is clear. Thanks once again

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [December 8, 2022, 5:19pm UTC](https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428/4 "2022-12-08T17:19:30Z")

</div>

> [@Phuntsho](#):
>
> v=[(1,15),(2,13),(4,13), (5,6)]

```julia
julia> using StatsBase

julia> collect(zip(first.(v),denserank(last.(v))))
4-element Vector{Tuple{Int64, Int64}}:
 (1, 3)
 (2, 2)
 (4, 2)
 (5, 1)

```

For more information about `denserank`, the usual, press `?` for help and type `denserank` will do.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [December 8, 2022, 5:22pm UTC](https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428/5 "2022-12-08T17:22:11Z")

</div>

Ok, in this case I would do this:

```julia
julia> using DataFrames, StatsBase

julia> df = DataFrame(student = first.(v), grade = last.(v))
30×2 DataFrame
 Row │ student grade
     │ Int64 Int64
─────┼────────────────
   1 │ 1 11
   2 │ 2 4
   3 │ 3 12
   4 │ 4 8
   5 │ 5 2
   6 │ 6 3
   7 │ 7 14
   8 │ 8 2
   9 │ 9 7
  10 │ 10 2
  11 │ 11 10
  12 │ 12 10
  13 │ 13 10
  14 │ 14 11
  15 │ 15 2
  16 │ 16 15
  17 │ 17 12
  18 │ 18 5
  19 │ 19 15
  20 │ 20 7
  21 │ 21 11
  22 │ 22 8
  23 │ 23 11
  24 │ 24 12
  25 │ 25 13
  26 │ 26 2
  27 │ 27 1
  28 │ 28 1
  29 │ 29 13
  30 │ 30 2

julia> df.rank = denserank(df.grade); sort!(df, :rank)
30×3 DataFrame
 Row │ student grade rank
     │ Int64 Int64 Int64
─────┼───────────────────────
   1 │ 27 1 1
   2 │ 28 1 1
   3 │ 5 2 2
   4 │ 8 2 2
   5 │ 10 2 2
   6 │ 15 2 2
   7 │ 26 2 2
   8 │ 30 2 2
   9 │ 6 3 3
  10 │ 2 4 4
  11 │ 18 5 5
  12 │ 9 7 6
  13 │ 20 7 6
  14 │ 4 8 7
  15 │ 22 8 7
  16 │ 11 10 8
  17 │ 12 10 8
  18 │ 13 10 8
  19 │ 1 11 9
  20 │ 14 11 9
  21 │ 21 11 9
  22 │ 23 11 9
  23 │ 3 12 10
  24 │ 17 12 10
  25 │ 24 12 10
  26 │ 25 13 11
  27 │ 29 13 11
  28 │ 7 14 12
  29 │ 16 15 13
  30 │ 19 15 13

```

You might of course have a good reason to work with vectors of tuples, but given your data and what you’re doing with it they seem a suboptimal data structure to me.

---

<div class="post-metadata">

**Author:** ![Phuntsho](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phuntsho/32/46546_2.png) [@Phuntsho](https://discourse.julialang.org/u/Phuntsho)\
**Post date:** [December 8, 2022, 5:25pm UTC](https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428/6 "2022-12-08T17:25:12Z")

</div>

Thank you very much, I love it.

---

<div class="post-metadata">

**Author:** ![Phuntsho](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phuntsho/32/46546_2.png) [@Phuntsho](https://discourse.julialang.org/u/Phuntsho)\
**Post date:** [December 8, 2022, 5:27pm UTC](https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428/7 "2022-12-08T17:27:50Z")

</div>

Thank you very much. I really appreciate your help. I liked your take on dataframe. Thanks again.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [December 9, 2022, 8:41am UTC](https://discourse.julialang.org/t/how-to-find-rankings-of-each-tuple-in-the-list-of-tuples/91428/8 "2022-12-09T08:41:29Z")

</div>

If you don’t want to depend on any package

```julia
l = length(v)
u = unique(last.(v))
map(i->(v[i][1],length(u)-count(>(v[i][2]), u)), 1:l)

```
