Подтвердить что ты не робот

Создание текущей счетной переменной в 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 и t.2 сыгранных матчей (т.е. экземпляры до указанной даты, что "DC" встречается в столбцах t. 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 это уравнение (относительно) simple = SUMPRODUCT, например:

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

где E4 - t.1m для obs # 4, A: A - дата, B: B - t.1, C: C - t.2 и т.д.

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

Ответ 1

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

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

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 и т.д. На каждом прогоне мы подсчитываем количество раз, когда команда появилась, и используйте это как результат для нового столбца.

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]))

Теперь наш dataframe выглядит так:

> 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

Ответ 2

На шаге создания данных убедитесь, что 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

Ответ 3

Кажется, что отдельные столбцы t.1m и t.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)]
}

Ответ 4

Чтобы выполнить это, используя тот же способ, что и вы упомянули:

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