DT:

HomeTeam       AwayTeam       Season      Htpoints  Atpoints
Mattersburg    Salzburg      2015/2016        3         0
Salzburg       Rapid Vienna  2015/2016        0         3
Admira         Mattersburg   2015/2016        3         0
Admira         Salzburg      2015/2016        1         1
Mattersburg    Ried          2015/2016        3         0
Ried           Salzburg      2015/2016        0         3
Altach         Mattersburg   2015/2016        3         0
Austria Vie    Mattersburg   2015/2016        3         0
Salzburg       Altach        2015/2016        3         0
Mattersburg    AC Wolfsberger2015/2016        3         0
Salzburg       Austria Vienna2015/2016        1         1
Rapid Vienna   Mattersburg   2015/2016        0         3
Sturm Graz     Salzburg      2015/2016        0         3
Salzburg       Grodig        2015/2016        3         0

Para calcular los puntos promedio de un equipo en los últimos 3 partidos en casa:

library(zoo)

roll <- function(x, n) { 
if (length(x) <= n) NaN 
else rollapply(x, list(-seq(n)), mean, fill = NaN)
}

transform(DT, last3.HT.av.points = ave(Htpoints,Season,HomeTeam, FUN = function(x) roll(x, 3)))

Lo anterior no es un problema. Por otra parte....

¿Existe alguna posibilidad de calcular los puntos promedio de los últimos 3 partidos independientemente de si un equipo juega en casa o fuera?

Salida deseada (solo muestra información para el equipo de Salzburgo):

HomeTeam       AwayTeam       Season      Htpoints  Atpoints   HT.av.last3  AT.av.last3
Mattersburg    Salzburg      2015/2016        3         0                        NA
Salzburg       Rapid Vienna  2015/2016        0         3           NA
Admira         Mattersburg   2015/2016        3         0
Admira         Salzburg      2015/2016        1         1                        NA
Mattersburg    Ried          2015/2016        3         0
Ried           Salzburg      2015/2016        0         3                        0.33
Altach         Mattersburg   2015/2016        3         0
Austria Vie    Mattersburg   2015/2016        3         0
Salzburg       Altach        2015/2016        3         0          1.33
Mattersburg    AC Wolfsberger2015/2016        3         0
Salzburg       Austria Vienna2015/2016        1         1          2.33
Rapid Vienna   Mattersburg   2015/2016        0         3
Sturm Graz     Salzburg      2015/2016        0         3                        2.33
Salzburg       Grodig        2015/2016        3         0          2.33

Preferencias: data.table

Conjunto de datos reproducible (no el mismo que el anterior):

 library(data.table)
 DT <- fread("HomeTeam,AwayTeam,Season,Htpoints,Atpoints
        Grodig,Salzburg,2015/2016,0,3
        Rapid Vienna,Altach,2015/2016,1,1
        Ried,Austria Vienna,2015/2016,3,0
        Sturm Graz,Mattersburg,2015/2016,3,0
        Admira,Rapid Vienna,2015/2016,1,1
        Altach,Ried,2015/2016,0,3
        Austria Vienna,Sturm Graz,2015/2016,1,1
        Mattersburg,Grodig,2015/2016,3,0
        Salzburg,AC Wolfsberger,2015/2016,3,0")

 numTeams <- DT[,uniqueN(c(HomeTeam, AwayTeam))]

 firstHalf <- lapply(seq_len(DT[,.N]),
                function(n) data.table(
                  Matchday=n*2L-1L,
                  HomeTeam=DT[["HomeTeam"]],
                  AwayTeam=c(DT[["AwayTeam"]][-seq_len(n)], DT[["AwayTeam"]][seq_len(n)]),
                  Season=DT[["Season"]],
                  Htpoints=DT[["Htpoints"]],
                  Atpoints=DT[["Atpoints"]]
                ))

 secondHalf <- lapply(seq_len(DT[,.N]),
                 function(n) data.table(
                   Matchday=n*2L,
                   HomeTeam=DT[["AwayTeam"]],
                   AwayTeam=c(DT[["HomeTeam"]][-seq_len(n)], DT[["HomeTeam"]][seq_len(n)]),
                   Season=DT[["Season"]],
                   Htpoints=DT[["Htpoints"]],
                   Atpoints=DT[["Atpoints"]]
                 ))


DT <- rbindlist(c(firstHalf, secondHalf))[
HomeTeam!=AwayTeam][,
            .SD[1L], by=.(HomeTeam, AwayTeam)]
setorder(DT, Matchday, HomeTeam)
DT <- DT[,-c("Matchday")]
r
0
William88 8 sep. 2018 a las 19:33

3 respuestas

La mejor respuesta

Usando DT que se muestra de forma reproducible en la Nota al final, agregue una columna de número de fila, i, y cree un data.table both que tenga dos filas para cada fila en DT, una para el Local y uno para el equipo visitante. Luego use rollapply en eso e inserte los resultados nuevamente en DT. Tenga en cuenta que no es necesario tener un código especial para manejar el caso donde hay menos de 3 filas anteriores para un equipo, ya que rollapply lo manejará automáticamente.

both <- rbind(
  DT[, list(HomeAway = "Home", Team = HomeTeam, Season, Points = Htpoints, i = .I)],
  DT[, list(HomeAway = "Away", Team = AwayTeam, Season, Points = Atpoints, i = .I)]
)

setkeyv(both, c("Season", "Team", "i"))
both[, Last3 := rollapply(Points, list(-seq(3)), mean, fill = NA_real_, na.rm = TRUE),
  by = "Season,Team"]

setkeyv(both, "i")
DT[, HtLast3 := both[HomeAway == "Home", Last3]][
   , AtLast3 := both[HomeAway == "Away", Last3]]

Dando:

> DT
        HomeTeam       AwayTeam    Season Htpoints Atpoints  HtLast3   AtLast3
 1:  Mattersburg       Salzburg 2015/2016        3        0       NA        NA
 2:     Salzburg   Rapid Vienna 2015/2016        0        3       NA        NA
 3:       Admira    Mattersburg 2015/2016        3        0       NA        NA
 4:       Admira       Salzburg 2015/2016        1        1       NA        NA
 5:  Mattersburg           Ried 2015/2016        3        0       NA        NA
 6:         Ried       Salzburg 2015/2016        0        3       NA 0.3333333
 7:       Altach    Mattersburg 2015/2016        3        0       NA 2.0000000
 8:  Austria Vie    Mattersburg 2015/2016        3        0       NA 1.0000000
 9:     Salzburg         Altach 2015/2016        3        0 1.333333        NA
10:  Mattersburg AC Wolfsberger 2015/2016        3        0 1.000000        NA
11:     Salzburg Austria Vienna 2015/2016        1        1 2.333333        NA
12: Rapid Vienna    Mattersburg 2015/2016        0        3       NA 1.0000000
13:   Sturm Graz       Salzburg 2015/2016        0        3       NA 2.3333333
14:     Salzburg         Grodig 2015/2016        3        0 2.333333        NA

Nota

DF <-
structure(list(HomeTeam = c("Mattersburg", "Salzburg", "Admira", 
"Admira", "Mattersburg", "Ried", "Altach", "Austria Vie", "Salzburg", 
"Mattersburg", "Salzburg", "Rapid Vienna", "Sturm Graz", "Salzburg"
), AwayTeam = c("Salzburg", "Rapid Vienna", "Mattersburg", "Salzburg", 
"Ried", "Salzburg", "Mattersburg", "Mattersburg", "Altach", "AC Wolfsberger", 
"Austria Vienna", "Mattersburg", "Salzburg", "Grodig"), Season = c("2015/2016", 
"2015/2016", "2015/2016", "2015/2016", "2015/2016", "2015/2016", 
"2015/2016", "2015/2016", "2015/2016", "2015/2016", "2015/2016", 
"2015/2016", "2015/2016", "2015/2016"), Htpoints = c(3L, 0L, 
3L, 1L, 3L, 0L, 3L, 3L, 3L, 3L, 1L, 0L, 0L, 3L), Atpoints = c(0L, 
3L, 0L, 1L, 0L, 3L, 0L, 0L, 0L, 0L, 1L, 3L, 3L, 0L)), 
class = "data.frame", row.names = c(NA, -14L))

DT <- as.data.table(DF)
1
G. Grothendieck 9 sep. 2018 a las 03:27

Tuve un momento difícil con su conjunto de datos, así que hice mi propio conjunto de datos que es como el suyo:

Home= sample(c("A","B","C","D"),9,replace = T)
Away= sample(c("A","B","C","D"),9,replace = T)
Home_Points= sample(c(0,1,3),9,replace = T)
Away_Points= sample(c(0,1,3),9,replace = T)

dt<-data.frame(HomeTeam=Home,
               AwayTeam=Away, 
               Htpoints=Home_Points,Atpoints=Away_Points,
               stringsAsFactors = FALSE)

Y mi conjunto de datos es:

  HomeTeam AwayTeam Htpoints Atpoints
1        C        C        0        1
2        D        B        1        1
3        D        B        3        0
4        A        B        0        3
5        C        D        1        3
6        C        A        1        3
7        C        D        1        1
8        D        A        1        3
9        D        B        3        3

Solución: combina los equipos Local y Visitante y sus puntos

team  <- as.vector(rbind(dt[,1],dt[,2]))
points<- as.vector(rbind(dt[,3],dt[,4]))

newDT<-data.frame( team=team,points=points,stringsAsFactors = FALSE)

Y finalmente sumar los puntos según el equipo, y sin importar el hogar o el visitante:

Biblioteca (tidyverse)

newDT %>%
  group_by(team) %>%
  summarise_all(sum) 

Y el resultado es:

 team  points
  <chr>  <dbl>
1 A          6
2 B          7
3 C          4
4 D         12

Punto

Si cree que la temporada también puede cambiar, también puede agregar temporada al nuevo conjunto de datos y luego ordenar en función de ello (arrange).

0
Salman Lashkarara 8 sep. 2018 a las 20:02
library(tidyverse)
library(zoo)

DT_prep <- DT %>% 
  as.tibble() %>% 
  mutate(row = row_number()) 

DT_rollmeans <- DT_prep %>% 
  gather(teamside, teamname, -Season, -Htpoints, -Atpoints, -row) %>% 
  arrange(row) %>% 
  group_by(teamname) %>% 
  mutate(points = case_when(teamside == 'HomeTeam' ~ Htpoints,
                            teamside == 'AwayTeam' ~ Atpoints),
         roll_mean = zoo::rollapply(points, 3, mean, align = 'right', fill = NA)) %>% 
  ungroup() %>% 
  select(row, teamside, roll_mean) %>%
  spread(teamside, roll_mean) %>% 
  select(row, HT.av.last3 = HomeTeam, AT.av.last3 = AwayTeam)



DT_prep %>% left_join(DT_rollmeans) %>% select(-row)

Esto produce un tibble que se ve de la siguiente manera:

# A tibble: 90 x 7
   HomeTeam       AwayTeam       Season    Htpoints Atpoints HT.av.last3 AT.av.last3
   <chr>          <chr>          <chr>        <int>    <int>       <dbl>       <dbl>
 1 Admira         Ried           2015/2016        1        1          NA      NA    
 2 Altach         Sturm Graz     2015/2016        0        3          NA      NA    
 3 Austria Vienna Grodig         2015/2016        1        1          NA      NA    
 4 Grodig         Altach         2015/2016        0        3          NA      NA    
 5 Mattersburg    AC Wolfsberger 2015/2016        3        0          NA      NA    
 6 Rapid Vienna   Austria Vienna 2015/2016        1        1          NA      NA    
 7 Ried           Mattersburg    2015/2016        3        0          NA      NA    
 8 Sturm Graz     Rapid Vienna   2015/2016        3        0          NA      NA    
 9 AC Wolfsberger Grodig         2015/2016        3        0          NA       0.333
10 Mattersburg    Admira         2015/2016        3        0           2      NA    
# ... with 80 more rows

Para los primeros 2 juegos para todos, el promedio es NA, después de eso es la media móvil de los 3 últimos juegos. El primer equipo en tener al menos tres juegos es Grodig en datos y tiene un promedio de 0.333 de anotar 1, 0 y 0 en los primeros 3 juegos.

No estoy contento con mi solución, pero funciona, estoy seguro de que alguien podría hacer esto mucho más compacto.

1
mkeskisa 8 sep. 2018 a las 17:56