Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in R Programming by (50.2k points)

I want to rank a variable in groups of two other variables. For that, I am applying frank() in data.table. 

Here is my data:

structure(list(indpn = c(170, 170, 170, 170, 170, 170, 9870, 

9870, 9870, 9870, 9870, 9870), occpn = c(6050, 9130, 205, 5120, 

5740, 6005, 3930, 700, 1410, 3645, 1050, 150), ncwc = c(258575, 

4747, 10742, 205, 867, 11026, 0, 0, 0, 0, 0, 0)), row.names = c(NA, 

-12L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x0000000000181ef0>)

This is the code I am using:

z[ , therank := frank( -ncwc , ties.method ="min" ) , by = .(indpn, occpn) ]

This is what I am receiving:

    indpn occpn   ncwc therank

 1:   170  6050 258575       1

 2:   170  9130   4747       1

 3:   170   205  10742       1

 4:   170  5120    205       1

 5:   170  5740    867       1

 6:   170  6005  11026       1

 7:  9870  3930      0       1

 8:  9870   700      0       1

 9:  9870  1410      0       1

10:  9870  3645      0       1

11:  9870  1050      0       1

12:  9870   150      0       1

I want the 'therank' variable to have these values:

1,4,3,6,5,2,1,1,1,1,1,1

1 Answer

0 votes
by (108k points)

I think you can group by the indpn column, as you can see, it is giving the expected output:

library(data.table)

z[ , therank := frank(-ncwc , ties.method ="min" ) ,indpn]

z

#    indpn occpn   ncwc therank

# 1:   170  6050 258575       1

# 2:   170  9130   4747       4

# 3:   170   205  10742       3

# 4:   170  5120    205       6

# 5:   170  5740    867       5

# 6:   170  6005  11026       2

# 7:  9870  3930      0       1

# 8:  9870   700      0       1

# 9:  9870  1410      0       1

#10:  9870  3645      0       1

#11:  9870  1050      0       1

#12:  9870   150      0       1

But, note that how the frank() behaves. I think, this is the output that you were want to get from frank:

z$ncwc[12] <- -1

z[ , therank := frank( -ncwc , ties.method ="min" ) ,indpn]

z

#    indpn occpn   ncwc therank

# 1:   170  6050 258575       1

# 2:   170  9130   4747       4

# 3:   170   205  10742       3

# 4:   170  5120    205       6

# 5:   170  5740    867       5

# 6:   170  6005  11026       2

# 7:  9870  3930      0       1

# 8:  9870   700      0       1

# 9:  9870  1410      0       1

#10:  9870  3645      0       1

#11:  9870  1050      0       1

#12:  9870   150     -1       6

And also if you want the last value to be 2 and not 6, then it is better to use the match with unique attribute:

z[order(-ncwc) , therank := match(ncwc, unique(ncwc)) ,indpn]

z

#    indpn occpn   ncwc therank

# 1:   170  6050 258575       1

# 2:   170  9130   4747       4

# 3:   170   205  10742       3

# 4:   170  5120    205       6

# 5:   170  5740    867       5

# 6:   170  6005  11026       2

# 7:  9870  3930      0       1

# 8:  9870   700      0       1

# 9:  9870  1410      0       1

#10:  9870  3645      0       1

#11:  9870  1050      0       1

#12:  9870   150     -1       2

If you are interested in R certification then do refer to the R programming certification

Browse Categories

...