R group by и aggregate - возвращает относительный ранг в группах, используя plyr
ОБНОВЛЕНИЕ: у меня есть фрейм данных 'test', который выглядит так:
session_id seller_feedback_score
1 1 282470
2 1 275258
3 1 275258
4 1 275258
5 1 37831
6 1 282470
7 1 26
8 1 138351
9 1 321350
10 1 841
11 1 138351
12 1 17263
13 1 282470
14 1 396900
15 1 282470
16 1 282470
17 1 321350
18 1 321350
19 1 321350
20 1 0
21 1 1596
22 7 282505
23 7 275283
24 7 275283
25 7 275283
26 7 37834
27 7 282505
28 7 26
29 7 138359
30 7 321360
и код (использующий пакет plyr), который, очевидно, должен ранжировать "seller_feedback_score" в каждой группе session_id:
test <- test %>% group_by(session_id) %>%
mutate(seller_feedback_score_rank = dense_rank(-seller_feedback_score))
однако на самом деле происходит то, что R ранжирует весь фрейм данных вместе, не связываясь с группами (session_id's):
session_id seller_feedback_score seller_feedback_score_rank_2
1 1 282470 5
2 1 275258 7
3 1 275258 7
4 1 275258 7
5 1 37831 11
6 1 282470 5
7 1 26 15
8 1 138351 9
9 1 321350 3
10 1 841 14
11 1 138351 9
12 1 17263 12
13 1 282470 5
14 1 396900 1
15 1 282470 5
16 1 282470 5
17 1 321350 3
18 1 321350 3
19 1 321350 3
20 1 0 16
21 1 1596 13
22 7 282505 4
23 7 275283 6
24 7 275283 6
25 7 275283 6
26 7 37834 10
27 7 282505 4
28 7 26 15
29 7 138359 8
30 7 321360 2
Я проверил это, посчитав уникальные значения "seller_feedback_score_rank", и неудивительно, что оно равно наибольшему значению ранга. Буду признателен, если кто-то сможет воспроизвести и помочь. Спасибо
2 ответа
Один вариант:
library(dplyr)
df %>% group_by(session_id) %>%
mutate(rank = dense_rank(-seller_feedback_score))
dense_rank
"как min_rank, но без пробелов между рангами", поэтому я отменил столбец seller_feedback_score, чтобы превратить его в нечто вроде max_rank (которого нет в dplyr).
Если вы хотите получить ранги с пробелами, чтобы вы достигли 21 для самого низкого в вашем случае, вы можете использовать min_rank
вместо dense_rank
:
library(dplyr)
df %>% group_by(session_id) %>%
mutate(rank = min_rank(-seller_feedback_score))
От data.table 1.9.5
на, frank()
(для быстрого ранга) функция экспортируется. Интерфейс похож на base::rank
, но это реализует dense rank
в дополнение ко всем методам ранжирования base::rank
обеспечивает, и это также работает над списком в дополнение к векторам. Вы можете установить его, следуя инструкциям здесь.
require(data.table) ## 1.9.5+
setDT(df)[,
rank := frank(-seller_feedback_score, ties.method="dense"),
by=session_id]
Как отмечает @David, возможно, вы хотите rank = "first"
или "мин"?? Точно сказать не могу...
setDT(df)[,
rank := frank(-seller_feedback_score, ties.method="first"), ## or "min" or "max"
by=session_id]
Во всяком случае, это должно быть быстро. Вот эталон против базы R:
require(data.table)
set.seed(45L)
val = sample(1e4, 1e7, TRUE)
system.time(ans1 <- rank(val, ties.method = "min"))
# user system elapsed
# 16.771 0.199 17.035
system.time(an2 <- frank(val, ties.method = "min"))
# user system elapsed
# 0.532 0.013 0.550
identical(ans1, ans2) # [1] TRUE