在我的游戏数据集中,我观察了几个时间点上的多个游戏玩家。对于每次观察,我都希望根据该点数与该时间点其他玩家的点数比较来计算该玩家的排名。因此,它必须将此观察者的得分与所有其他游戏者在其最后一个(或在时间上最近的时间或恰好在同一秒)观察其他所有用户的得分数进行比较。
包含预期排名的示例数据:
da = data.frame(player = c(1,1,1,2,2,2,3,3,3), date_sec = c(1451665633,1451665693,1451665721,1451665627,1451665692,1451665738,1451665626,1451665684,1451665765), points = c(100,150,200,130,140,230,80,90,100), rank = c(2,1,1,1,1,1,1,3,3))
da
player date_sec points rank
1 1 1451665633 100 2
2 1 1451665693 150 1
3 1 1451665721 200 1
4 2 1451665627 130 1
5 2 1451665692 140 1
6 2 1451665738 230 1
7 3 1451665626 80 1
8 3 1451665684 90 3
9 3 1451665765 100 3
[[例如,玩家2在date_sec 1451665738中的排名为1,因为在这个时间点上,没有其他玩家获得更多的分数。
我知道如何在组中进行排名,但是在这里我找不到找到将确切时间点考虑在内的方法。一种方法是从时间戳中提取日期,然后按天和玩家分组,但这并不像我想要的那样准确,因为排名可以在一天之内改变几次。library(dplyr)
da2 = mutate(da, day = as.Date(as.POSIXct(date_sec, origin="1970-01-01"))) %>%
group_by(player, day) %>%
mutate(my_ranks = order(order(points, day, decreasing=TRUE)))
da2
A tibble: 9 x 6
# Groups: player, day [3]
player date_sec points rank day my_ranks
<dbl> <dbl> <dbl> <dbl> <date> <int>
1 1 1451665633 100 2 2016-01-01 3
2 1 1451665693 150 1 2016-01-01 2
3 1 1451665721 200 1 2016-01-01 1
4 2 1451665627 130 1 2016-01-01 3
5 2 1451665692 140 2 2016-01-01 2
6 2 1451665738 230 2 2016-01-01 1
7 3 1451665626 80 3 2016-01-01 3
8 3 1451665684 90 3 2016-01-01 2
9 3 1451665765 100 3 2016-01-01 1
在排名旁边,我也想根据分数来确定百分等级,因为在不同时间段内活跃的玩家数量不同。有人有想法吗?
complete
,以便每个player
/ date_sec
组合都有一行。这将使每个时刻的比较更加容易。接下来,我将使用fill
结转每个玩家的最新分数。分数应在此之前排序/排列。
然后,由于每个时间戳都有一个分数,因此您可以group_by(date_sec)
并在每个时间对球员进行排名。
最后,您可以重新加入原始数据框以提供所需的排名。
library(tidyverse)
da %>%
complete(player, date_sec) %>%
group_by(player) %>%
arrange(date_sec) %>%
fill(points) %>%
group_by(date_sec) %>%
mutate(my_ranks = order(order(points, decreasing = TRUE))) %>%
right_join(da)
输出
Joining, by = c("player", "date_sec", "points", "rank") # A tibble: 9 x 5 # Groups: date_sec [9] player date_sec points rank my_ranks <dbl> <dbl> <dbl> <dbl> <int> 1 1 1451665633 100 2 2 2 1 1451665693 150 1 1 3 1 1451665721 200 2 1 4 2 1451665627 130 1 1 5 2 1451665692 140 2 1 6 2 1451665738 230 1 1 7 3 1451665626 80 3 1 8 3 1451665684 90 3 3 9 3 1451665765 100 3 3