Noura
Noura

Reputation: 474

How to rank a column with a condition

I have a data frame :

dt <- read.table(text = "
1 390 
1 366
1 276 
1 112 
2 97
2 198  
2 400  
2 402
3 110
3 625
4 137
4 49
4 9
4 578 ")

The first colomn is Index and the second is distance.

I want to add a colomn to rank the distance by Index in a descending order (the highest distance will be ranked first)

The result will be :

dt <- read.table(text = "
1 390 1
1 66  4
1 276 2
1 112 3
2 97  4
2 198 3 
2 300 2
2 402 1
3 110 2
3 625 1
4 137 2
4 49  3
4 9   4
4 578 1")

Upvotes: 0

Views: 61

Answers (3)

Nettle
Nettle

Reputation: 3321

You could group, arrange, and rownumber. The result is a bit easier on the eyes than a simple rank, I think, and so worth an extra step.

dt %>% 
  group_by(V1) %>% 
  arrange(V1,desc(V2)) %>% 
  mutate(rank = row_number())

# A tibble: 14 x 3
# Groups:   V1 [4]
      V1    V2  rank
   <int> <int> <int>
 1     1   390     1
 2     1   366     2
 3     1   276     3
 4     1   112     4
 5     2   402     1
 6     2   400     2
 7     2   198     3
 8     2    97     4
 9     3   625     1
10     3   110     2
11     4   578     1
12     4   137     2
13     4    49     3
14     4     9     4

A scrambled alternative is min_rank

dt %>% 
  group_by(V1) %>% 
  mutate(min_rank(desc(V2)) )

Upvotes: 0

Jilber Urbina
Jilber Urbina

Reputation: 61214

Another R base approach

> dt$Rank <- unlist(tapply(-dt$V2, dt$V1, rank))

A tidyverse solution

dt %>% 
  group_by(V1) %>% 
  mutate(Rank=rank(-V2))

Upvotes: 2

Onyambu
Onyambu

Reputation: 79388

transform(dt,s = ave(-V2,V1,FUN = rank))
   V1  V2 s
1   1 390 1
2   1  66 4
3   1 276 2
4   1 112 3
5   2  97 4
6   2 198 3
7   2 300 2
8   2 402 1
9   3 110 2
10  3 625 1
11  4 137 2
12  4  49 3
13  4   9 4
14  4 578 1

Upvotes: 1

Related Questions