Реструктуризация соревнования / данные гонки - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть данные о гоночных соревнованиях, состоящие из времени гонки для участника, его позиции в гонке, независимой переменной x и гонки. Я ищу способ предсказать исход в новой гонке. Не только победитель, но и весь рейтинг. Вот как выглядят данные:

df <- data.frame(                                      
competitor = c("A", "B", "C", "A", "B", "C", "D"),     
time = c(54.2, 48.3, 49.1, 105.2, 116.2, 112.5, 117.3),
position = c(3,1,2,1,3,2,4),                           
x = c(4, 6, 2, 3, 7, 5, 2),                            
race = c("race1", "race1", "race1",                    
"race2", "race2", "race2", "race2")                    
)                                                      

#>   competitor  time position x  race
#> 1          A  54.2        3 4 race1
#> 2          B  48.3        1 6 race1
#> 3          C  49.1        2 2 race1
#> 4          A 105.2        1 3 race2
#> 5          B 116.2        3 7 race2
#> 6          C 112.5        2 5 race2
#> 7          D 117.3        4 2 race2

Одна идея, которая у меня возникла, состояла в том, чтобы реструктурировать данные таким образом, чтобы каждый конкурент "конкурировал" с любым другим конкурентом. Затем данные должны быть реструктурированы, чтобы выглядеть примерно так для первой гонки:

df_wide <- data.frame(                       
competitor = c("A", "B", "A", "C", "B", "C"),
opponent = c("B", "A", "C", "A", "C", "B"),  
time = c(54.2,48.3, 54.2, 49.1, 48.3, 49.1), 
x = c(3,1,3,2,1,2),                          
win = c(0,1,0,1,1,0),                        
race = c("race1"))                           

#>   competitor opponent time x win  race
#> 1          A        B 54.2 3   0 race1
#> 2          B        A 48.3 1   1 race1
#> 3          A        C 54.2 3   0 race1
#> 4          C        A 49.1 2   1 race1
#> 5          B        C 48.3 1   1 race1
#> 6          C        B 49.1 2   0 race1

Тогда я полагаю, что смогу смоделировать вероятность того, что А победит над В в новой гонке и, таким образом, предсказать позицию.

Кто-нибудь знает удобный способ реструктуризации таких данных?

1 Ответ

0 голосов
/ 26 апреля 2018

Хороший вопрос.

Если я не слишком усложняю вещи, я считаю, что ключ ко всему этому - использование outer с < в качестве функции. Например, позиции в первой гонке были:

pos <- c("A" = 3, "B" = 1, "C" = 2)

Мы можем получить матрицу всех возможных сравнений выигрыша / проигрыша следующим образом:

(res <- outer(pos, pos, `<`))
#>       A     B     C
#> A FALSE FALSE FALSE
#> B  TRUE FALSE  TRUE
#> C  TRUE FALSE FALSE

Затем мы можем превратить это в подходящий фрейм данных, используя gather и некоторые другие приемы. Но, в конце концов, это должно быть сделано для каждой расы, а затем все это объединено и объединено с исходным кадром данных. Итак, нам нужно определить функцию, которая выполняет эту работу. Вот оно:

library(tidyverse)
all_pairs <- function(df) {
  pmat <- outer(df$position, df$position, `<`)
  rownames(pmat) <- colnames(pmat) <- df$competitor
  as.data.frame(pmat) %>% 
    rownames_to_column(var = "competitor") %>% 
    gather(opponent, win, -competitor) %>% 
    mutate(win=as.integer(win)) %>% 
    filter(competitor != opponent)
}

Давайте попробуем это на первой гонке:

all_pairs(df[1:3,])
#>   competitor opponent win
#> 1          B        A   1
#> 2          C        A   1
#> 3          A        B   0
#> 4          C        B   0
#> 5          A        C   0
#> 6          B        C   1

Я решил использовать split и lapply. Функция bind_rows имеет хороший способ восстановить переменную race. Вот окончательный ответ:

left_join(df,
          bind_rows(lapply(split(df, factor(df$race)), all_pairs), .id = "race")) %>% 
  select(competitor, opponent, time, x, win, race)
#> Joining, by = c("competitor", "race")
#> # A tibble: 18 x 6
#>    competitor opponent  time     x   win race 
#>    <chr>      <chr>    <dbl> <dbl> <int> <chr>
#>  1 A          B         54.2    4.     0 race1
#>  2 A          C         54.2    4.     0 race1
#>  3 B          A         48.3    6.     1 race1
#>  4 B          C         48.3    6.     1 race1
#>  5 C          A         49.1    2.     1 race1
#>  6 C          B         49.1    2.     0 race1
#>  7 A          B        105.     3.     1 race2
#>  8 A          C        105.     3.     1 race2
#>  9 A          D        105.     3.     1 race2
#> 10 B          A        116.     7.     0 race2
#> 11 B          C        116.     7.     0 race2
#> 12 B          D        116.     7.     1 race2
#> 13 C          A        112.     5.     0 race2
#> 14 C          B        112.     5.     1 race2
#> 15 C          D        112.     5.     1 race2
#> 16 D          A        117.     2.     0 race2
#> 17 D          B        117.     2.     0 race2
#> 18 D          C        117.     2.     0 race2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...