问题
Using my example below, how can I rank multiple columns using different orders, so for example rank y as descending and z as ascending?
require(data.table)
dt <- data.table(x = c(rep("a", 5), rep("b", 5)),
y = abs(rnorm(10)) * 10, z = abs(rnorm(10)) * 10)
cols <- c("y", "z")
dt[, paste0("rank_", cols) := lapply(.SD, function(x) frankv(x, ties.method = "min")), .SDcols = cols, by = .(x)]
回答1:
data.table's frank() function has some useful features which aren't available in base R's rank() function (see ?frank). E.g., we can reverse the order of the ranking by prepending the variable with a minus sign:
library(data.table)
# create reproducible data
set.seed(1L)
dt <- data.table(x = c(rep("a", 5), rep("b", 5)),
y = abs(rnorm(10)) * 10, z = abs(rnorm(10)) * 10)
# rank y descending, z ascending
dt[, rank_y := frank(-y), x][, rank_z := frank(z), x][]
x y z rank_y rank_z 1: a 6.264538 15.1178117 3 4 2: a 1.836433 3.8984324 5 1 3: a 8.356286 6.2124058 2 2 4: a 15.952808 22.1469989 1 5 5: a 3.295078 11.2493092 4 3 6: b 8.204684 0.4493361 1 2 7: b 4.874291 0.1619026 4 1 8: b 7.383247 9.4383621 2 5 9: b 5.757814 8.2122120 3 4 10: b 3.053884 5.9390132 5 3
If there are many columns which are to be ranked individually, some descending, some ascending, we can do this in two steps
# first rank all columns in descending order
cols_desc <- c("y")
dt[, paste0("rank_", cols_desc) := lapply(.SD, frankv, ties.method = "min", order = -1L),
.SDcols = cols_desc, by = x][]
# then rank all columns in ascending order
cols_asc <- c("z")
dt[, paste0("rank_", cols_asc) := lapply(.SD, frankv, ties.method = "min", order = +1L),
.SDcols = cols_asc, by = x][]
x y z rank_y rank_z 1: a 6.264538 15.1178117 3 4 2: a 1.836433 3.8984324 5 1 3: a 8.356286 6.2124058 2 2 4: a 15.952808 22.1469989 1 5 5: a 3.295078 11.2493092 4 3 6: b 8.204684 0.4493361 1 2 7: b 4.874291 0.1619026 4 1 8: b 7.383247 9.4383621 2 5 9: b 5.757814 8.2122120 3 4 10: b 3.053884 5.9390132 5 3
来源:https://stackoverflow.com/questions/46280337/ranking-multiple-columns-by-different-orders-using-data-table