Создание текущей Счетной переменной в 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')