分组数据中考虑时间戳的排名计算
Rank computation considering time stamp in grouped data
在我的游戏数据集中,我有几个游戏玩家在几个时间点的观察结果。对于每次观察,我想根据此时点数与其他玩家的点数相比,计算该玩家的排名。因此,它必须将这次观察的这个玩家的点数与所有其他玩家在他们最后一次(或过去时间上最接近的或恰好在同一秒)观察其他每个用户的点数进行比较。
包含预期排名的示例数据:
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
结转每个玩家的最近得分。在此之前的分数应该是sorted/arranged
然后,因为你有每个时间戳的分数,你可以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
在我的游戏数据集中,我有几个游戏玩家在几个时间点的观察结果。对于每次观察,我想根据此时点数与其他玩家的点数相比,计算该玩家的排名。因此,它必须将这次观察的这个玩家的点数与所有其他玩家在他们最后一次(或过去时间上最接近的或恰好在同一秒)观察其他每个用户的点数进行比较。
包含预期排名的示例数据:
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
结转每个玩家的最近得分。在此之前的分数应该是sorted/arranged
然后,因为你有每个时间戳的分数,你可以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