微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 data.table

如何解决使用 data.table

我有一些足球数据(2020/2021 意甲),我想计算每支球队在过去 n 天里的比赛数量(可以说是在过去 30 天里简化)。因此,条件是球队,比赛当天(严格小于)和同一天 - 30(大于或等于)。

我想知道使用 data.table(单独)的最佳方法是什么,更重要的是,代码背后的逻辑。我会遍历团队和日期,但我认为这很麻烦,而且我相信有一种方法可以在一行中完成。

下面给出了一个示例,结果是我所期望的(日期和日期可能会产生误导,因为有些比赛被推迟了,但这并不重要。数据按日期分类)。非常感谢。

代码 团队 日期 日期 - 30 天 过去 30 天内玩过的游戏
TORATA 亚特兰大 2020-09-26 2 2020-08-27 不适用
拉扎塔 亚特兰大 2020-09-30 1 2020-08-31 1
ATACAG 亚特兰大 2020-10-04 3 2020-09-04 2
NAPATA 亚特兰大 2020-10-17 4 2020-09-17 3
ATASAM 亚特兰大 2020-10-24 5 2020-09-24 4
克罗地亚 亚特兰大 2020-10-31 6 2020-10-01 3
ATAINT 亚特兰大 2020-11-08 7 2020-10-09 3

解决方法

这是一个实现,只有 data.table 和基础 R:

dat[,z := sapply(Date,function(z) sum(between(z - Date,0.1,30)))]
dat
#      Code     Team       Date   Day Date...30d Games.played.over.the.last.30.days     z
#    <char>   <char>     <Date> <int>     <Date>                              <int> <int>
# 1: TORATA Atalanta 2020-09-26     2 2020-08-27                                 NA     0
# 2: LAZATA Atalanta 2020-09-30     1 2020-08-31                                  1     1
# 3: ATACAG Atalanta 2020-10-04     3 2020-09-04                                  2     2
# 4: NAPATA Atalanta 2020-10-17     4 2020-09-17                                  3     3
# 5: ATASAM Atalanta 2020-10-24     5 2020-09-24                                  4     4
# 6: CROATA Atalanta 2020-10-31     6 2020-10-01                                  3     3
# 7: ATAINT Atalanta 2020-11-08     7 2020-10-09                                  3     3

在这种情况下,对于每个 Date 值,我们计算其 30 天内有多少个日期。

如果您需要 NA 代替 0,那么您可以添加 dat[z < 1,z := NA] 或类似内容。


数据:

library(data.table)
dat <- structure(list(Code = c("TORATA","LAZATA","ATACAG","NAPATA","ATASAM","CROATA","ATAINT"),Team = c("Atalanta","Atalanta","Atalanta"),Date = structure(c(18531,18535,18539,18552,18559,18566,18574),class = "Date"),Day = c(2L,1L,3L,4L,5L,6L,7L),Date...30d = structure(c(18501,18505,18509,18522,18529,18536,18544),Games.played.over.the.last.30.days = c(NA,2L,3L)),class = c("data.table","data.frame"),row.names = c(NA,-7L))
setDT(dat)
,

您可以将 runnerdata.table 结合使用来计算正在运行的 Date 窗口数:

library(data.table)
library(runner)

setDT(data)

data[,Date:=as.Date(Date,'%Y-%m-%d')]

data[,N:=runner::runner(
                        x = Date,k = 30,# 30-days window
                        lag = 1,idx = Date,f = length),by=Team][]

     Code     Team       Date Day    Date30d Games30days N
1: TORATA Atalanta 2020-09-26   2 2020-08-27          NA 0
2: LAZATA Atalanta 2020-09-30   1 2020-08-31           1 1
3: ATACAG Atalanta 2020-10-04   3 2020-09-04           2 2
4: NAPATA Atalanta 2020-10-17   4 2020-09-17           3 3
5: ATASAM Atalanta 2020-10-24   5 2020-09-24           4 4
6: CROATA Atalanta 2020-10-31   6 2020-10-01           3 3
7: ATAINT Atalanta 2020-11-08   7 2020-10-09           3 3

数据:

data <- read.table(text='
Code    Team    Date    Day     Date30d     Games30days
TORATA  Atalanta    2020-09-26  2   2020-08-27  NA
LAZATA  Atalanta    2020-09-30  1   2020-08-31  1
ATACAG  Atalanta    2020-10-04  3   2020-09-04  2
NAPATA  Atalanta    2020-10-17  4   2020-09-17  3
ATASAM  Atalanta    2020-10-24  5   2020-09-24  4
CROATA  Atalanta    2020-10-31  6   2020-10-01  3
ATAINT  Atalanta    2020-11-08  7   2020-10-09  3',header=T)
,

您可以通过一行代码实现这一点,使用表与自身的非等连接。

假设 fb 是您的输入数据(没有 Games30days 列)。像这样:

     Code     Team       Date Day Date - 30d
1: TORATA Atalanta 2020-09-26   2 2020-08-27
2: LAZATA Atalanta 2020-09-30   1 2020-08-31
3: ATACAG Atalanta 2020-10-04   3 2020-09-04
4: NAPATA Atalanta 2020-10-17   4 2020-09-17
5: ATASAM Atalanta 2020-10-24   5 2020-09-24
6: CROATA Atalanta 2020-10-31   6 2020-10-01
7: ATAINT Atalanta 2020-11-08   7 2020-10-09

然后,只需在 Team=TeamDate<DateDate>Date - 30d 上进行联接,如下所示:

games_played = fb[fb,on=.(Team = Team,Date<Date,Date>`Date - 30d`),nomatch=0][,.("Games30" =  .N),.(Date,Team)]

哪个返回

         Date     Team Games30
1: 2020-09-30 Atalanta       1
2: 2020-10-04 Atalanta       2
3: 2020-10-17 Atalanta       3
4: 2020-10-24 Atalanta       4
5: 2020-10-31 Atalanta       3
6: 2020-11-08 Atalanta       3

该结果可以很容易地连接回原始数据,以获取所有列,如下所示:

games_played[fb,on=.(Team,Date)]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。