1

I have a data.table like this

ds <- data.table(ID = c(1,1,1,1,1,2,2,2,2,2),
                 Month = c("Jan", "Feb", "Mar", "Apr", "May", "Jan", "Feb", "Mar", "Apr", "May"),
                 val = c(1,2,3,4,5,6,7,8,9,10))

ds
   ID Month val
1:  1   Jan   1
2:  1   Feb   2
3:  1   Mar   3
4:  1   Apr   4
5:  1   May   5
6:  2   Jan   6
7:  2   Feb   7
8:  2   Mar   8
9:  2   Apr   9
10:  2   May  10

I want my data.table where within each ID group, I rearrange Month order like this

    ID Month val
4:   1   Apr   4
5:   1   May   5
1:   1   Jan   1
2:   1   Feb   2
3:   1   Mar   3
9:   2   Apr   9
10:  2   May  10
6:   2   Jan   6
7:   2   Feb   7
8:   2   Mar   8

I want per group, the order of Month as Apr, May, Jan, Feb, Mar

How can I achieve this?

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
Hardik Gupta
  • 4,700
  • 9
  • 41
  • 83
  • 1
    Related post: https://stackoverflow.com/questions/2375587/reorder-levels-of-a-factor-without-changing-order-of-values – zx8754 Oct 30 '17 at 07:37

1 Answers1

6

We can use the order in the i by converting the "Month" to factor with levels specified in the custom order

ds[order(factor(Month, levels = c("Apr", "May", "Jan", "Feb", "Mar"))), .SD,ID]
#    ID Month val
# 1:  1   Apr   4
# 2:  1   May   5
# 3:  1   Jan   1
# 4:  1   Feb   2
# 5:  1   Mar   3
# 6:  2   Apr   9
# 7:  2   May  10
# 8:  2   Jan   6
# 9:  2   Feb   7
#10:  2   Mar   8

Or another option is match

ds[order(match(Month, c("Apr", "May", "Jan", "Feb", "Mar"))), .SD,ID]

Instead of specifying it one by one, we can also make use of month.abb i.e. month.abb[c(4:5, 1:3)] to replace the c("Apr", "May", "Jan", "Feb", "Mar")

akrun
  • 874,273
  • 37
  • 540
  • 662