Computing points for a football team

亡梦爱人 提交于 2021-02-10 14:59:30

问题


everyone. I am trying to calculate football team points. I have my dataframe "df.work" with rownames = teamnames: rownames(df.work) <- c(as.vector(teams$HomeTeam))

I have imported all played matches from another dataframe. And for every team I try to execute if loop based on subset of team matches. First I filter all home matches. So my code is

for (Team1 in row.names.data.frame(df.work)){
a1 <- filter(df.clean, HomeTeam == Team1)
  if (a1$home.goals > a1$away.goals) {
    df.work[Team1,"Points"] <- df.work[Team1,"Points"] + 3
  } else  if(a1$home.goals == a1$away.goals) {
    df.work[Team1,"Points"] <- df.work[Team1,"Points"] + 1
  }

But I struggle why it did not loop for every row in a1 and sum the points?

Edit: this is head(df.clean):

        HomeTeam         AwayTeam home.goals away.goals
1      Liverpool          Norwich          4          1
2       West Ham         Man City          0          5
3    Bournemouth Sheffield United          1          1
4        Burnley      Southampton          3          0
5 Crystal Palace          Everton          0          0
6        Watford         Brighton          0          3

and head(df.work) is

               Games Goals.Scored Goals.Conceded Points 
Liverpool         32           70             25      3 
West Ham          32           38             56      0
Bournemouth       32           30             54      1
Burnley           32           36             45      3
Crystal Palace    32           28             37      1
Watford           32           29             49      0 

回答1:


Here's a dplyr solution to transform df.clean into the desired result without using loops. The data set was easy enough to replicate from public resources.

library(dplyr)
library(tidyr)

df.clean %>% 
  pivot_longer(1:2, names_to = "HA", values_to = "Team") %>% 
  group_by(Team) %>%
  mutate(Goals.Conceded = ifelse(HA == "HomeTeam", away.goals, home.goals)) %>%
  mutate(Goals.Scored = ifelse(HA == "HomeTeam", home.goals, away.goals)) %>%
  mutate(Points = ifelse(Goals.Scored > Goals.Conceded, 3,
                         ifelse(Goals.Scored == Goals.Conceded, 1, 0))) %>%
  mutate(Games = 1) %>% 
  select(c(8, 6:5, 7)) %>% 
  summarise_all(sum) %>%
  arrange(-Points)

Which yields:

#> # A tibble: 20 x 5
#>    Team           Games Goals.Scored Goals.Conceded Points
#>    <fct>          <dbl>        <dbl>          <dbl>  <dbl>
#>  1 Liverpool         32           70             25     86
#>  2 Man City          32           81             33     66
#>  3 Leicester         32           60             31     55
#>  4 Chelsea           32           57             44     54
#>  5 Man Utd           32           51             31     52
#>  6 Wolves            32           45             34     52
#>  7 Sheffield Utd     32           33             32     47
#>  8 Arsenal           32           47             41     46
#>  9 Burnley           32           36             45     45
#> 10 Spurs             32           51             44     45
#> 11 Everton           32           40             47     44
#> 12 Crystal Palace    32           28             37     42
#> 13 Newcastle         32           33             43     42
#> 14 Southampton       32           41             55     40
#> 15 Brighton          32           34             44     33
#> 16 West Ham          32           38             56     30
#> 17 Watford           32           29             49     28
#> 18 Aston Villa       32           36             60     27
#> 19 Bournemouth       32           30             54     27
#> 20 Norwich           32           25             60     21

Data

df.clean <- structure(list(HomeTeam = structure(c(10L, 19L, 3L, 5L, 7L, 18L, 
17L, 9L, 13L, 12L, 1L, 2L, 4L, 8L, 14L, 16L, 11L, 15L, 6L, 20L, 
2L, 14L, 4L, 12L, 15L, 18L, 10L, 3L, 17L, 20L, 16L, 6L, 7L, 9L, 
11L, 13L, 19L, 5L, 8L, 1L, 10L, 4L, 12L, 15L, 17L, 20L, 14L, 
3L, 18L, 2L, 16L, 9L, 5L, 8L, 11L, 13L, 7L, 19L, 1L, 6L, 15L, 
3L, 2L, 6L, 7L, 17L, 20L, 8L, 9L, 12L, 4L, 5L, 10L, 14L, 18L, 
19L, 1L, 11L, 16L, 13L, 8L, 3L, 2L, 6L, 9L, 17L, 20L, 7L, 12L, 
15L, 16L, 11L, 4L, 18L, 19L, 5L, 13L, 1L, 10L, 14L, 3L, 1L, 2L, 
4L, 11L, 15L, 19L, 18L, 7L, 8L, 14L, 6L, 5L, 13L, 16L, 17L, 9L, 
12L, 20L, 10L, 19L, 3L, 1L, 4L, 7L, 8L, 18L, 11L, 15L, 2L, 13L, 
5L, 6L, 10L, 17L, 16L, 14L, 20L, 9L, 12L, 7L, 5L, 9L, 20L, 12L, 
6L, 16L, 10L, 15L, 1L, 8L, 3L, 17L, 18L, 11L, 2L, 13L, 14L, 4L, 
19L, 10L, 5L, 6L, 9L, 15L, 16L, 12L, 20L, 1L, 7L, 8L, 3L, 2L, 
4L, 13L, 14L, 11L, 18L, 17L, 17L, 3L, 2L, 6L, 7L, 8L, 15L, 12L, 
9L, 20L, 4L, 13L, 16L, 18L, 14L, 19L, 5L, 1L, 10L, 11L, 4L, 5L, 
13L, 16L, 18L, 11L, 14L, 19L, 1L, 10L, 15L, 7L, 6L, 8L, 9L, 12L, 
20L, 17L, 3L, 2L, 18L, 1L, 4L, 11L, 14L, 16L, 19L, 13L, 5L, 10L, 
3L, 2L, 8L, 15L, 7L, 6L, 9L, 17L, 12L, 20L, 19L, 9L, 3L, 7L, 
10L, 13L, 18L, 19L, 12L, 5L, 17L, 8L, 4L, 15L, 20L, 16L, 14L, 
2L, 1L, 6L, 11L, 6L, 5L, 7L, 15L, 16L, 9L, 12L, 20L, 1L, 10L, 
14L, 4L, 3L, 13L, 19L, 18L, 8L, 17L, 10L, 1L, 7L, 15L, 16L, 20L, 
5L, 6L, 12L, 9L, 2L, 11L, 14L, 17L, 18L, 4L, 19L, 3L, 13L, 2L, 
8L, 11L, 9L, 17L, 12L, 13L, 14L, 20L, 10L, 5L, 16L, 6L, 2L, 18L, 
7L, 4L, 3L, 1L, 8L, 19L, 15L, 11L), .Label = c("Arsenal", "Aston Villa", 
"Bournemouth", "Brighton", "Burnley", "Chelsea", "Crystal Palace", 
"Everton", "Leicester", "Liverpool", "Man City", "Man Utd", "Newcastle", 
"Norwich", "Sheffield Utd", "Southampton", "Spurs", "Watford", 
"West Ham", "Wolves"), class = "factor"), AwayTeam = structure(c(14L, 
11L, 15L, 16L, 8L, 4L, 2L, 20L, 1L, 6L, 5L, 3L, 19L, 18L, 13L, 
10L, 17L, 7L, 9L, 12L, 8L, 6L, 16L, 7L, 9L, 19L, 1L, 11L, 13L, 
5L, 12L, 15L, 2L, 3L, 4L, 18L, 14L, 10L, 20L, 17L, 13L, 5L, 9L, 
16L, 7L, 6L, 11L, 8L, 1L, 19L, 3L, 17L, 14L, 15L, 18L, 4L, 20L, 
12L, 2L, 10L, 10L, 19L, 5L, 4L, 14L, 16L, 18L, 11L, 13L, 1L, 
17L, 8L, 9L, 2L, 15L, 7L, 3L, 20L, 6L, 12L, 19L, 14L, 4L, 13L, 
5L, 18L, 16L, 11L, 10L, 1L, 9L, 2L, 8L, 3L, 15L, 6L, 20L, 7L, 
17L, 12L, 12L, 20L, 10L, 14L, 16L, 5L, 13L, 6L, 9L, 17L, 18L, 
7L, 19L, 3L, 8L, 15L, 1L, 4L, 2L, 11L, 17L, 20L, 16L, 9L, 10L, 
14L, 5L, 6L, 12L, 13L, 11L, 7L, 19L, 4L, 3L, 18L, 1L, 15L, 8L, 
2L, 3L, 11L, 18L, 19L, 17L, 2L, 14L, 8L, 13L, 4L, 6L, 10L, 5L, 
7L, 12L, 9L, 16L, 15L, 20L, 1L, 18L, 13L, 3L, 14L, 2L, 19L, 8L, 
17L, 11L, 4L, 1L, 5L, 16L, 15L, 7L, 20L, 9L, 12L, 6L, 4L, 1L, 
14L, 16L, 19L, 5L, 18L, 13L, 10L, 11L, 3L, 8L, 7L, 2L, 17L, 9L, 
12L, 6L, 20L, 15L, 6L, 2L, 9L, 17L, 20L, 8L, 7L, 3L, 12L, 15L, 
19L, 1L, 5L, 4L, 16L, 14L, 13L, 10L, 18L, 11L, 17L, 15L, 2L, 
7L, 3L, 20L, 8L, 6L, 9L, 12L, 4L, 18L, 13L, 11L, 16L, 1L, 19L, 
14L, 5L, 10L, 10L, 6L, 2L, 15L, 16L, 14L, 8L, 4L, 20L, 1L, 11L, 
7L, 18L, 3L, 9L, 5L, 10L, 17L, 13L, 12L, 19L, 17L, 3L, 13L, 4L, 
2L, 11L, 18L, 14L, 8L, 19L, 9L, 7L, 6L, 5L, 16L, 10L, 12L, 20L, 
3L, 19L, 18L, 14L, 13L, 4L, 17L, 8L, 11L, 2L, 15L, 1L, 16L, 12L, 
9L, 1L, 20L, 7L, 15L, 6L, 10L, 5L, 4L, 19L, 15L, 2L, 8L, 3L, 
7L, 18L, 1L, 11L, 20L, 16L, 5L, 12L, 13L, 14L, 9L, 6L, 17L, 10L
), .Label = c("Arsenal", "Aston Villa", "Bournemouth", "Brighton", 
"Burnley", "Chelsea", "Crystal Palace", "Everton", "Leicester", 
"Liverpool", "Man City", "Man Utd", "Newcastle", "Norwich", "Sheffield Utd", 
"Southampton", "Spurs", "Watford", "West Ham", "Wolves"), class = "factor"), 
    home.goals = c(4, 0, 1, 3, 0, 0, 3, 0, 0, 4, 2, 1, 1, 1, 
    3, 1, 2, 1, 1, 1, 2, 2, 0, 1, 1, 1, 3, 1, 0, 1, 1, 2, 1, 
    3, 4, 1, 2, 0, 3, 2, 3, 1, 1, 0, 4, 2, 3, 3, 2, 0, 1, 2, 
    2, 0, 8, 0, 1, 2, 3, 1, 0, 2, 2, 2, 2, 2, 2, 1, 5, 1, 3, 
    1, 2, 1, 0, 1, 1, 0, 1, 1, 2, 0, 2, 1, 2, 1, 1, 0, 1, 1, 
    0, 3, 3, 0, 1, 2, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 1, 0, 
    1, 0, 2, 3, 2, 1, 1, 2, 3, 2, 3, 2, 1, 2, 0, 1, 0, 0, 2, 
    3, 2, 2, 0, 0, 2, 3, 2, 2, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 
    5, 0, 1, 3, 0, 5, 0, 1, 1, 2, 1, 2, 1, 2, 1, 0, 1, 2, 0, 
    1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 3, 2, 0, 2, 1, 1, 0, 2, 1, 
    1, 4, 0, 3, 2, 1, 1, 3, 2, 1, 0, 1, 1, 2, 1, 1, 0, 1, 2, 
    2, 1, 4, 2, 2, 1, 1, 3, 1, 1, 4, 1, 0, 0, 1, 0, 1, 1, 2, 
    1, 2, 1, 1, 2, 2, 3, 2, 2, 0, 0, 2, 4, 2, 0, 1, 0, 2, 2, 
    0, 4, 0, 2, 3, 0, 0, 2, 3, 1, 2, 0, 1, 0, 2, 4, 0, 2, 2, 
    3, 1, 1, 2, 0, 3, 3, 3, 3, 1, 0, 2, 0, 3, 3, 1, 2, 2, 1, 
    1, 1, 0, 0, 1, 4, 2, 4, 0, 3, 0, 1, 1, 2, 0, 0, 3, 1, 0, 
    5, 0, 2, 3, 1, 0, 1, 4, 1, 0, 2, 0, 1, 0, 0, 1, 4, 2, 3, 
    3, 4), away.goals = c(1, 5, 1, 0, 0, 3, 1, 0, 1, 0, 1, 2, 
    1, 0, 1, 2, 2, 0, 1, 1, 0, 3, 2, 2, 2, 3, 1, 3, 1, 1, 1, 
    2, 0, 1, 0, 1, 0, 3, 2, 2, 1, 1, 0, 1, 0, 5, 2, 1, 2, 0, 
    3, 1, 0, 2, 0, 0, 1, 0, 2, 2, 1, 2, 2, 0, 0, 1, 0, 3, 0, 
    1, 0, 0, 1, 5, 0, 2, 0, 2, 4, 0, 0, 0, 1, 0, 1, 1, 1, 2, 
    1, 0, 9, 0, 2, 0, 1, 4, 1, 2, 1, 3, 0, 1, 2, 0, 1, 0, 3, 
    2, 2, 1, 2, 0, 0, 1, 2, 1, 0, 1, 1, 1, 3, 2, 2, 2, 2, 2, 
    3, 1, 3, 0, 2, 2, 1, 1, 2, 1, 2, 1, 1, 2, 0, 4, 0, 0, 1, 
    1, 1, 2, 2, 2, 1, 3, 0, 0, 2, 4, 1, 2, 2, 3, 0, 0, 1, 1, 
    0, 1, 1, 2, 3, 1, 0, 1, 3, 1, 0, 2, 1, 0, 2, 1, 1, 0, 2, 
    1, 0, 1, 1, 4, 2, 0, 2, 1, 0, 2, 2, 2, 2, 0, 0, 1, 2, 3, 
    0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, 1, 3, 6, 0, 1, 
    1, 2, 0, 3, 1, 0, 1, 0, 1, 1, 2, 1, 2, 2, 1, 1, 2, 2, 2, 
    2, 1, 1, 0, 0, 3, 3, 0, 0, 0, 1, 1, 1, 0, 2, 1, 3, 0, 2, 
    0, 1, 0, 0, 1, 0, 1, 0, 0, 2, 2, 0, 1, 2, 0, 1, 0, 1, 3, 
    1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 0, 
    2, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 2, 1, 1, 3, 1, 3, 4, 0, 
    1, 2, 1, 0)), row.names = c(NA, 320L), class = "data.frame")



回答2:


I believe the following is what the question asks for.

goals2points <- function(x, y){
  pnts <- sign(x - y) + 1
  pnts[pnts == 2] <- 3
  sum(pnts)
}

hg <- aggregate(home.goals ~ HomeTeam, df.clean, sum)
ag <- aggregate(away.goals ~ AwayTeam, df.clean, sum)
Goals.Scored <- hg[[2]] + ag[[2]]
hg <- aggregate(home.goals ~ AwayTeam, df.clean, sum)
ag <- aggregate(away.goals ~ HomeTeam, df.clean, sum)
Goals.Conceded <- hg[[2]] + ag[[2]]

sp1 <- split(df.clean, df.clean$HomeTeam)
home <- sapply(sp1, function(DF){
  goals2points(DF[['home.goals']], DF[['away.goals']])
})

sp2 <- split(df.clean, df.clean$AwayTeam)
away <- sapply(sp2, function(DF){
  goals2points(DF[['away.goals']], DF[['home.goals']])
})

Points <- rowSums(cbind(home, away))
result <- data.frame(Games = lengths(sp1) + lengths(sp2), 
                     Goals.Scored, 
                     Goals.Conceded, 
                     Points)
result
#  Games Goals.Scored Goals.Conceded Points
#A     8           24             22     12
#B     8           26             21     15
#C     8           23             21     12
#D     8           17             24      7
#E     8           23             25     13

Test data

set.seed(2020)
df.clean <- expand.grid(HomeTeam = LETTERS[1:5], AwayTeam = LETTERS[1:5])
df.clean <- df.clean[apply(df.clean, 1, function(x) x[1] != x[2]), ]
df.clean$home.goals <- sample(0:5, nrow(df.clean), TRUE)
df.clean$away.goals <- sample(0:5, nrow(df.clean), TRUE)


来源:https://stackoverflow.com/questions/62740230/computing-points-for-a-football-team

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!