#r
#r
Вопрос:
Я хотел бы найти эффективный способ суммирования количества очков, полученных командой в предыдущих N матчах (не включая очки в текущем матче) для каждой комбинации simulation_ID, team и season . Если команда сыграла менее N матчей, функция должна вернуть NA.
Упрощенный набор данных:
match_ID | сезон | simulation_ID | домашняя команда | Команда | match_result | team_points |
---|---|---|---|---|---|---|
1 | 2015-2016 | 1 | ВЕРНО | Манчестер Юнайтед | Главная победа | 3 |
1 | 2015-2016 | 2 | ВЕРНО | Манчестер Юнайтед | Нарисовать | 1 |
1 | 2015-2016 | 3 | ВЕРНО | Манчестер Юнайтед | Главная победа | 3 |
1 | 2015-2016 | 1 | ЛОЖЬ | Tottenham | Главная победа | 0 |
1 | 2015-2016 | 2 | ЛОЖЬ | Tottenham | Главная победа | 0 |
1 | 2015-2016 | 3 | ЛОЖЬ | Tottenham | Победа гостей | 3 |
2 | 2015-2016 | 1 | ВЕРНО | Лестер | Главная победа | 3 |
2 | 2015-2016 | 2 | ВЕРНО | Лестер | Главная победа | 3 |
2 | 2015-2016 | 3 | ВЕРНО | Лестер | Победа гостей | 0 |
2 | 2015-2016 | 1 | ЛОЖЬ | Сандерленд | Нарисовать | 1 |
Ожидаемый результат — это дополнительный столбец в данных, называемый ‘accumulated_team_points’, который возвращает очки в последних N матчах для этой команды, сезона и simulation_ID.
Кажется, я не могу найти способ сделать это.
Комментарии:
1. Пожалуйста, покажите ожидаемый результат
2. Я отредактировал свой вопрос, это то, что вы имели в виду?
3. Tor97, цель состоит в том, чтобы вы показали, что, по вашему мнению, подобная операция должна в конечном итоге предоставить в качестве своих результатов. Если вы видите мой ответ, я демонстрирую, что даже в таком, казалось бы, простом вопросе, как этот, есть варианты, которые дают разные результаты. В хороших вопросах по SO часто можно найти попытки написания кода, образцы данных, ожидаемый результат с учетом этих выборочных данных и часто предупреждения / ошибки, которые являются проблематичными.
Ответ №1:
Здесь вам понадобятся две операции: группировка (я продемонстрирую с dplyr
помощью) и суммирование в режиме скользящего окна (я буду использовать zoo
).
Кроме того, ваши данные слишком скудны, чтобы их можно было группировать по всем трем team, season, simulation_ID
, поэтому я просто покажу группировку к team
этому времени. Для ваших больших данных замените group_by(team)
на group_by(team, season, simulation_ID)
.
library(dplyr)
k <- 3 # window size
dat %>%
group_by(team) %>%
mutate(accumulated_team_points = zoo::rollapply(team_points, k, FUN = sum, align = "right", fill = NA)) %>%
ungroup()
# # A tibble: 10 x 8
# match_ID season simulation_ID home_team team match_result team_points accumulated_team_points
# <int> <chr> <int> <lgl> <chr> <chr> <int> <int>
# 1 1 2015-2016 1 TRUE Manchester Utd Home win 3 NA
# 2 1 2015-2016 2 TRUE Manchester Utd Draw 1 NA
# 3 1 2015-2016 3 TRUE Manchester Utd Home win 3 7
# 4 1 2015-2016 1 FALSE Tottenham Home win 0 NA
# 5 1 2015-2016 2 FALSE Tottenham Home win 0 NA
# 6 1 2015-2016 3 FALSE Tottenham Away win 3 3
# 7 2 2015-2016 1 TRUE Leicester Home win 3 NA
# 8 2 2015-2016 2 TRUE Leicester Home win 3 NA
# 9 2 2015-2016 3 TRUE Leicester Away win 0 6
# 10 2 2015-2016 1 FALSE Sunderland Draw 1 NA
По умолчанию NA
используется значение для первых k-1
экземпляров в окне, что обычно является разумным и оправданным значением по умолчанию. Однако, если вы хотите суммировать даже частичные суммы, замените fill=NA
на partial=TRUE
:
dat %>%
group_by(team) %>%
mutate(accumulated_team_points = zoo::rollapply(team_points, k, FUN = sum, align = "right", partial = TRUE)) %>%
ungroup()
# # A tibble: 10 x 8
# match_ID season simulation_ID home_team team match_result team_points accumulated_team_points
# <int> <chr> <int> <lgl> <chr> <chr> <int> <int>
# 1 1 2015-2016 1 TRUE Manchester Utd Home win 3 3
# 2 1 2015-2016 2 TRUE Manchester Utd Draw 1 4
# 3 1 2015-2016 3 TRUE Manchester Utd Home win 3 7
# 4 1 2015-2016 1 FALSE Tottenham Home win 0 0
# 5 1 2015-2016 2 FALSE Tottenham Home win 0 0
# 6 1 2015-2016 3 FALSE Tottenham Away win 3 3
# 7 2 2015-2016 1 TRUE Leicester Home win 3 3
# 8 2 2015-2016 2 TRUE Leicester Home win 3 6
# 9 2 2015-2016 3 TRUE Leicester Away win 0 6
# 10 2 2015-2016 1 FALSE Sunderland Draw 1 1
К вашему сведению: я предполагаю, что данные предварительно упорядочены.
Данные
dat <- structure(list(match_ID = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), season = c("2015-2016", "2015-2016", "2015-2016", "2015-2016", "2015-2016", "2015-2016", "2015-2016", "2015-2016", "2015-2016", "2015-2016"), simulation_ID = c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L), home_team = c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE), team = c("Manchester Utd", "Manchester Utd", "Manchester Utd", "Tottenham", "Tottenham", "Tottenham", "Leicester", "Leicester", "Leicester", "Sunderland"), match_result = c("Home win", "Draw", "Home win", "Home win", "Home win", "Away win", "Home win", "Home win", "Away win", "Draw"), team_points = c(3L, 1L, 3L, 0L, 0L, 3L, 3L, 3L, 0L, 1L)), class = "data.frame", row.names = c(NA, -10L))
Комментарии:
1. Невероятно, именно то, что мне было нужно! Спасибо. Я запомню ‘rollapply’.
2. Может сократить прокатную часть до:
zoo::rollsumr(team_points, k, fill = NA)