Создание текущей Счетной переменной в R?

у меня есть набор данных результатов футбольного матча, и я надеюсь узнать R, создав Бегущий набор рейтингов, подобных формуле World Football Elo. У меня проблемы с вещами, которые кажутся простыми в Excel, не совсем интуитивно понятны в R. например, первые 15 из 4270 наблюдений с необходимыми переменными:

       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

Я хочу иметь возможность создать новую переменную, которая будет работать количество t.1 и т. 2 всего сыгранных матчей (т. е. инстансы на сегодняшний день в вопрос о том, что "ДК" происходит в колонках Т.1 или T.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

в Excel это (относительно) простое уравнение =SUMPRODUCT, e.g:

E4=SUMPRODUCT((A:A<=A4)*(B:B=B4))+SUMPRODUCT((A:A<=A4)*(C:C=B4))

где Е4 Т.1м для обс # 4, А: "дата", Б:Б Т.1, C:п-т.2 и т. д.

но в R я могу получить общий продукт, напечатанный для меня (т. е. " DC " сыграл 576 игр в моем наборе данных), но по какой-то причине (вероятно, я новый, нетерпеливый, потрясенный методом проб и ошибок) я просто потерялся в том, как сделать запуск рассчитывать на данные наблюдений, и особенно как сделать этот запуск рассчитывать в переменную, которая имеет жизненно важное значение для любого индекса рейтинга игры. Я знаю, что "PlayerRatings" существует, я чувствую, что для моего образования R я должен быть в состоянии сделать это в R suite без этого пакета. 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

4 ответов


вот очень простое решение, которое не очень красиво, но делает свою работу.

во-первых, просто изменение ваших данных, чтобы сделать сравнение проще:

mtable<-data.frame(date,t.1,t.2,m.result, stringsAsFactors = FALSE)

редактировать в:

если вы хотите заверить, что матчи заказаны по дате, вы можете использовать order как указано @eipi10:

mtable = mtable[order(mtable$date), ]

просто обратите внимание, что если даты находятся в формате, который хронологический порядок не является целочисленным порядком, вы можете сначала преобразуйте их в формат даты, используя as.Date().


то, что мы собираемся сделать, это для каждой строки взять подмножество фрейма данных со столбцами t.1 и t.2, со всеми строками от 1 до указанной строки. Так что ... 1:1, 1:2, 1:3, etc. При каждом запуске мы подсчитываем количество появлений этой команды и используем это в качестве результата для нового столбца.

mtable$t.1m <- sapply(1:nrow(mtable),
             function(i) sum(mtable[1:i, c("t.1", "t.2")] == mtable$t.1[i]))

это было сделано для команд 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]))

теперь наш фрейм данных выглядит так:

> 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

на этапе создания данных убедитесь, что stringsAsFactors = FALSE чтобы избежать проблем. Тогда это легко сделать. (Edit: я сделал это все 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

похоже, что отдельные столбцы t.1м и т. 2m для бухгалтерского учета, и вы действительно просто заинтересованы в количестве сыгранных игр? Я использовал with() для работы со столбцами mtable без необходимости писать mtable каждый раз

mtable$games <- with(mtable, {

если конкретная команда играет, она играет как команда 1 или команда 2

    played <- t.1 == "DC" | t.2 == "DC"

сравнение векторизуется, сравнивая каждый элемент столбца t.1 с " DC " и т. д., а логическое сравнение также векторизовано так, что один |.

хитрая часть данных заключается в том, что несколько команд играют в один день, и в день матча (по-видимому) только фокусная команда должна быть увеличена. Я приспособился к этому, выяснив, как заказать игры, чтобы команда фокуса всегда была последней в порядке в день, когда она играла

    o <- order(date, played)

затем рассчитывается совокупная сумма сыгранных игр

    games <- cumsum(played[o])

и вернуть игры в исходное состояние заказ

    games[order(o)]
})

> вот и результат

> head(mtable, 11)
       date t.1  t.2 m.result games
1  19960406  DC   SJ      0.0     1
2  19960413 COL   KC      0.0     1
3  19960413  NE   TB      0.0     1
4  19960413 CLB   DC      1.0     2
5  19960413 LAG NYRB      1.0     1
6  19960414 FCD   SJ      0.5     2
7  19960418 FCD   KC      1.0     2
8  19960420  NE NYRB      1.0     2
9  19960420  DC  LAG      0.0     3
10 19960420 CLB   TB      0.0     2
11 19960421 COL  FCD      1.0     3

вот функция, которая реализует это, что позволяет легко спецификации фокусной команды

gamesplayed <- function(date, t1, t2, focal="DC") {
    played <- t1 == focal | t2 == focal
    o <- order(date, played)
    cumsum(played[o])[order(o)]
}

чтобы выполнить это, используя аналогичный способ, как вы упомянули:

sum(mtable$t.1 == 'DC', mtable$t.2 == 'DC')