Mat*_*ger 13 r time-series running-total
我有足球比赛结果的数据集,我希望通过创建一组类似于World Football Elo公式的运行评级来学习R. 我遇到麻烦,在Excel中似乎很简单的东西在R中并不完全直观.例如,4270个观察中的前15个带有必要的变量:
date t.1 t.2 m.result
1 19960406 DC SJ 0.0
2 19960413 COL KC 0.0
3 19960413 NE TB 0.0
4 19960413 CLB DC 1.0
5 19960413 LAG NYRB 1.0
6 19960414 FCD SJ 0.5
7 19960418 FCD KC 1.0
8 19960420 NE NYRB 1.0
9 19960420 DC LAG 0.0
10 19960420 CLB TB 0.0
11 19960421 COL FCD 1.0
12 19960421 SJ KC 0.5
13 19960427 CLB NYRB 1.0
14 19960427 DC NE 0.5
15 19960428 FCD TB 1.0
Run Code Online (Sandbox Code Playgroud)
我希望能够创建一个新的变量,该变量将是t.1和t.2的总匹配的运行计数(即,直到所讨论的日期的实例,"DC"出现在列t.1或t中0.2):
date t.1 t.2 m.result ##t.1m ##t.2m
1 19960406 DC SJ 0.0 1 1
2 19960413 COL KC 0.0 1 1
3 19960413 NE TB 0.0 1 1
4 19960413 CLB DC 1.0 1 2
5 19960413 LAG NYRB 1.0 1 1
6 19960414 FCD SJ 0.5 1 2
7 19960418 FCD KC 1.0 2 2
8 19960420 NE NYRB 1.0 2 2
9 19960420 DC LAG 0.0 3 2
10 19960420 CLB TB 0.0 2 2
11 19960421 COL FCD 1.0 2 3
12 19960421 SJ KC 0.5 3 3
13 19960427 CLB NYRB 1.0 3 3
14 19960427 DC NE 0.5 4 3
15 19960428 FCD TB 1.0 4 3
Run Code Online (Sandbox Code Playgroud)
在Excel中,这是一个(相对)简单= SUMPRODUCT等式,例如:
E4=SUMPRODUCT((A:A<=A4)*(B:B=B4))+SUMPRODUCT((A:A<=A4)*(C:C=B4))
Run Code Online (Sandbox Code Playgroud)
对于障碍物#4,E4为t.1m,A:A为日期,B:B为t.1,C:C为t.2,等等.
但是在R中,我可以为我打印完整的sumproduct(即"DC"在我的数据集中玩了576个游戏),但由于某种原因(可能是我是新的,不耐烦,因试错而烦恼)我只是失去了如何对观察数据进行运行计数,尤其是如何将运行计数变为变量,这对任何游戏评级指数都至关重要.我知道'PlayerRatings'存在,我觉得对于我的R教育我应该能够在没有那个包的R套件中做到这一点.当然,plyr或dplyr没问题.
作为参考,这里是我的数据,您可以复制/粘贴到您的R.
date<-c(19960406,19960413,19960413,19960413,19960413,19960414,19960418,19960420,19960420,19960420,19960421,19960421,19960427,19960427,19960428)
t.1<-c("DC","COL","NE","CLB","LAG","FCD","FCD","NE","DC","CLB","COL","SJ","CLB","DC","FCD")
t.2<-c("SJ","KC","TB","DC","NYRB","SJ","KC","NYRB","LAG","TB","FCD","KC","NYRB","NE","TB")
m.result<-c(0.0,0.0,0.0,1.0,1.0,0.5,1.0,1.0,0.0,0.0,1.0,0.5,1.0,0.5,1.0)
mtable<-data.frame(date,t.1,t.2,m.result)
mtable
Run Code Online (Sandbox Code Playgroud)
在数据创建步骤中,请务必stringsAsFactors = FALSE避免出现问题.然后这很容易做到.(编辑:我把它作为一个dplyr例子)
library(dplyr)
cross_count <- function(id, var) {
length(which(mtable[id, var] == mtable[1:id, ] %>% select(t.1, t.2) %>% unlist))
}
mtable %>%
arrange(date) %>% # This makes sure the dates are in order
mutate(id = 1:nrow(.)) %>%
rowwise() %>%
mutate(t.1m = cross_count(id, 2), t.2m = cross_count(id, 3))
date t.1 t.2 m.result id t.1m t.2m
1 19960406 DC SJ 0.0 1 1 1
2 19960413 COL KC 0.0 2 1 1
3 19960413 NE TB 0.0 3 1 1
4 19960413 CLB DC 1.0 4 1 2
5 19960413 LAG NYRB 1.0 5 1 1
6 19960414 FCD SJ 0.5 6 1 2
7 19960418 FCD KC 1.0 7 2 2
8 19960420 NE NYRB 1.0 8 2 2
9 19960420 DC LAG 0.0 9 3 2
10 19960420 CLB TB 0.0 10 2 2
11 19960421 COL FCD 1.0 11 2 3
12 19960421 SJ KC 0.5 12 3 3
13 19960427 CLB NYRB 1.0 13 3 3
14 19960427 DC NE 0.5 14 4 3
15 19960428 FCD TB 1.0 15 4 3
Run Code Online (Sandbox Code Playgroud)
这是一个非常简单的解决方案,虽然不太漂亮,但可以完成工作。
首先,只需更改您的数据即可使比较更容易:
mtable<-data.frame(date,t.1,t.2,m.result, stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)
编辑于:
如果您想确保比赛按日期排序,您可以使用order@eipi10 指出的:
mtable = mtable[order(mtable$date), ]
Run Code Online (Sandbox Code Playgroud)
请注意,如果日期的格式按时间顺序不是整数顺序,您可以首先使用 将它们转换为日期格式as.Date()。
我们要做的是,对于每一行,获取包含列 和 的数据帧的子集t.1,t.2以及从 1 到所述行的所有行。因此,1:1、1:2、1:3 等。每次运行时,我们都会计算该团队出现的次数,并将其用作新列的结果。
mtable$t.1m <- sapply(1:nrow(mtable),
function(i) sum(mtable[1:i, c("t.1", "t.2")] == mtable$t.1[i]))
Run Code Online (Sandbox Code Playgroud)
这是为 中的团队完成的,在我们可以为 进行此操作t.1后,对参数进行了小改动:==t.2
mtable$t.2m <- sapply(1:nrow(mtable),
function(i) sum(mtable[1:i, c("t.1", "t.2")] == mtable$t.2[i]))
Run Code Online (Sandbox Code Playgroud)
现在我们的数据框如下所示:
> mtable
date t.1 t.2 m.result t.1m t.2m
1 19960406 DC SJ 0.0 1 1
2 19960413 COL KC 0.0 1 1
3 19960413 NE TB 0.0 1 1
4 19960413 CLB DC 1.0 1 2
5 19960413 LAG NYRB 1.0 1 1
6 19960414 FCD SJ 0.5 1 2
7 19960418 FCD KC 1.0 2 2
8 19960420 NE NYRB 1.0 2 2
9 19960420 DC LAG 0.0 3 2
10 19960420 CLB TB 0.0 2 2
11 19960421 COL FCD 1.0 2 3
12 19960421 SJ KC 0.5 3 3
13 19960427 CLB NYRB 1.0 3 3
14 19960427 DC NE 0.5 4 3
15 19960428 FCD TB 1.0 4 3
Run Code Online (Sandbox Code Playgroud)