2

I have a data frame with 2 columns: 'sales' and 'month'. I want to add a column that ranks the sales within each month. Does anyone know what's the most succinct way of doing so? I'm thinking of 'tapply' but it gives me a list and I can't add it back to the data frame (easily or succinctly).

Sales Month      Rank
100   1          3
200   2          1
300   3          1
150   1          2
220   1          1

100 is third place amongst sales that belong to month 1 while 220 is first place for month 1. 
user2864154
  • 455
  • 2
  • 6
  • 15
  • 1
    Possible duplicate of [Add a "rank" column to a data frame](http://stackoverflow.com/questions/15170777/add-a-rank-column-to-a-data-frame) – agenis Sep 15 '16 at 15:17

2 Answers2

3

We can use ave from base R to create the column

df1$Rank <- with(df1, ave(-Sales, Month, FUN = rank))
df1$Rank
#[1] 3 1 1 2 1

Or another succinct and efficient option is data.table. Convert the 'data.frame' to 'data.table' (setDT(df1)), grouped by 'Month', we assign (:=) the rank of 'Sales' to create 'Rank'

library(data.table)
setDT(df1)[, Rank := rank(-Sales) , Month]
akrun
  • 874,273
  • 37
  • 540
  • 662
1

You can use dplyr library:

library(dplyr)
df = data.frame(sales=c(100, 200, 300, 150, 220), month=c(1,2,3,1,1))
df %>% group_by(month) %>% mutate(rank(desc(sales)))

Though I think the quetion is a duplicate of this one

Community
  • 1
  • 1
agenis
  • 8,069
  • 5
  • 53
  • 102