2017-04-05 65 views
0

我有一个数据框,它遵循以下格式。带R条件语句的汇总滚动平均值

match team1 team2 winningTeam 
1  A  D  A 
2  B  E  E 
3  C  F  C 
4  D  C  C 
5  E  B  B 
6  F  A  A 
7  A  D  D 
8  D  A  A 

我想要做的是打包变量,计算队伍1和2的形式在最后的x比赛。例如,我想要创建一个名为team1_form_last3_matches的变量,对于匹配8,它将是0.33(因为他们赢得了他们最后3场比赛中的1场),并且还会有一个变量叫做team2_form_last3_matches,在比赛8中将是0.66(因为他们赢了他们最近3场比赛中的2场)。理想情况下,我希望能够指定在计算团队时要考虑的以前匹配的数量x _form_last y变量以及要自动创建的变量。我尝试了一堆使用dplyr,动物园滚动平均函数和嵌套for/if语句的方法。但是,我并没有完全破解它,当然也不是以一种优雅的方式。我觉得我错过了这个通用问题的简单解决方案。任何帮助将非常感激!

干杯,

杰克

回答

0

这适用于t1l3,您将需要复制它T2。

dat <- data.frame(match = c(1:8), team1 = c("A","B","C","D","E","F","A","D"), team2 = c("D","E","F","C","B","A","D","A"), winningTeam = c("A","E","C","C","B","A","D","A"),stringsAsFactors = FALSE) 

dat$t1l3 <- c(NA,sapply(2:nrow(dat),function(i) { 
    df <- dat[1:(i-1),] #just previous games, i.e. excludes current game 
    df <- df[df$team1==dat$team1[i] | df$team2==dat$team1[i],] #just those containing T1 
    df <- tail(df,3) #just the last three (or fewer if there aren't three previous games) 
    return(sum(df$winningTeam==dat$team1[i])/nrow(df)) #total wins/total games (up to three) 
})) 
+0

嗨。感谢您回复并回答。我今天在想,这种结构的某些东西可以发挥最佳效果。我尝试了上述方法,它几乎可行,但在我的场景中,我想要获得除当前比赛之外的最后三场比赛的结果 - 我认为上述内容将包括在内?此外,为什么上面不会创建一个团队发生的前两次NAs(因为没有足够的数据来计算最后三种形式)。再次感谢! –

+0

嗨,杰克。以上应该排除当前的游戏 - 也就是'dat [1:(i-1)]'这个词。 'tail'将给出data.frame(或向量等)的最后部分,直到指定的元素数量。现在你提到它,如果前三场比赛少于三场,那么除数就不应该是三! - 以上修改。 –

0

如何像:

dat <- data.frame(match = c(1:8), team1 = c("A","B","C","D","E","F","A","D"), team2 = c("D","E","F","C","B","A","D","A"), winningTeam = c("A","E","C","C","B","A","D","A")) 
    match team1 team2 winningTeam 
1  1  A  D   A 
2  2  B  E   E 
3  3  C  F   C 
4  4  D  C   C 
5  5  E  B   B 
6  6  F  A   A 
7  7  A  D   D 
8  8  D  A   A 

Allteams <- c("A","B","C","D","E","F") 

# A vectorized function for you to use to do as you ask: 
teamX_form_lastY <- function(teams, games, dat){ 
    sapply(teams, function(x) { 
    games_info <- rowSums(dat[,c("team1","team2")] == x) + (dat[,"winningTeam"] == x) 
    lookup <- ifelse(rev(games_info[games_info != 0])==2,1,0) 
    games_won <- sum(lookup[1:games]) 
    if(length(lookup) < games) warning(paste("maximum games for team",x,"should be",length(lookup))) 
    games_won/games 
    }) 
} 

teamX_form_lastY("A", 4, dat) 
A 
0.75 

# Has a warning for the number of games you should be using 
teamX_form_lastY("A", 5, dat) 
A 
NA 
Warning message: 
    In FUN(X[[i]], ...) : maximum games for team A should be 4 

# vectorized input 
teamX_form_lastY(teams = c("A","B"), games = 2, dat = dat) 
A B 
0.5 0.5 

# so you ca do all teams 
teamX_form_lastY(teams = Allteams, 2, dat) 
A B C D E F 
0.5 0.5 1.0 0.5 0.5 0.0 
+0

查看上面更新的答案。 –

+0

嗨埃文。谢谢回复!这也有效,但我更喜欢另一种解决方案,因为它直接将数据输出到数据框中。 –

+0

我同意你的意见。干杯〜 –