R group by and aggregate - return 使用 plyr 的组内相对排名
R group by and aggregate - return relative rank within groups using 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 包)显然应该在每组 session_id 中对 'seller_feedback_score' 进行排名:
test <- test %>% group_by(session_id) %>%
mutate(seller_feedback_score_rank = dense_rank(-seller_feedback_score))
然而,真正发生的是 R 将整个数据框放在一起而不与组相关(session_id):
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' 值来检查这一点,毫不奇怪它等于最高排名值。如果有人可以重现和提供帮助,我将不胜感激。谢谢
一个选项:
library(dplyr)
df %>% group_by(session_id) %>%
mutate(rank = dense_rank(-seller_feedback_score))
dense_rank
是 "like min_rank, but with no gaps between ranks" 所以我否定了 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
,但除了 base::rank
提供的所有排名方法外,它还实现了 dense rank
,并且除了向量之外,它还适用于列表。您可以按照说明进行安装 here.
require(data.table) ## 1.9.5+
setDT(df)[,
rank := frank(-seller_feedback_score, ties.method="dense"),
by=session_id]
正如@David 指出的那样,也许您想要的是 rank = "first"
或 "min"?不确定...
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
更新:我有一个数据框 '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 包)显然应该在每组 session_id 中对 'seller_feedback_score' 进行排名:
test <- test %>% group_by(session_id) %>%
mutate(seller_feedback_score_rank = dense_rank(-seller_feedback_score))
然而,真正发生的是 R 将整个数据框放在一起而不与组相关(session_id):
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' 值来检查这一点,毫不奇怪它等于最高排名值。如果有人可以重现和提供帮助,我将不胜感激。谢谢
一个选项:
library(dplyr)
df %>% group_by(session_id) %>%
mutate(rank = dense_rank(-seller_feedback_score))
dense_rank
是 "like min_rank, but with no gaps between ranks" 所以我否定了 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
,但除了 base::rank
提供的所有排名方法外,它还实现了 dense rank
,并且除了向量之外,它还适用于列表。您可以按照说明进行安装 here.
require(data.table) ## 1.9.5+
setDT(df)[,
rank := frank(-seller_feedback_score, ties.method="dense"),
by=session_id]
正如@David 指出的那样,也许您想要的是 rank = "first"
或 "min"?不确定...
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