R: Создать таблицу рекордов выигрыша / проигрыша против определенных игроков - PullRequest
0 голосов
/ 10 ноября 2018

Допустим, у меня есть следующие данные:

dat <- read.table(text="p1 p2 outcome
jon joe 1-0
jon james 0-1
james ken 1-0
ken jon 1-0", header=T)

Я пытаюсь использовать dplyr для вывода сводной таблицы статистики какого-то конкретного игрока (например, Джона) против каждого другого игрока в кадре данных. Итак, вывод должен быть:

joe: 1-0
james: 1-0
ken: 0-1

Я хочу использовать 'group_by' для работы с корпусом игр joe, но не знаю, как реализовать условные group_by (например, group_by joe, если p1 или p2 == joe). Я мог мутировать, чтобы создать фиктивный столбец, равный 1, если любое из этих условий выполняется, и group_by, но надеялся, что была более экономная стратегия. И затем, единственный способ, которым я могу видеть подсчет «выигрыша» для Джо, - это использовать выражение ifelse, согласно которому, если p1 == Джо и исход == 1-0 или p2 == Джо и исход == 0-1, тогда посчитайте это победой Джо. Однако не уверен, как это сделать, если операторы внутри трубопровода dplyr.

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

Вот альтернативное tidyverse решение:

# example data
dat <- read.table(text="
p1 p2 outcome
jon joe 1-0
jon james 0-1
james ken 1-0
ken jon 1-0", header=T, stringsAsFactors=F)

library(tidyverse)

# reshape your dataset
dat2 = dat %>%
  mutate(game_id = row_number()) %>%  # add game id
  unite(p, p1, p2, sep="-") %>%       # combine player names
  separate_rows(p, outcome)           # separate rows using name and scores

# get summary stats for jon
dat2 %>%
  group_by(game_id) %>%               # for each game id
  filter("jon" %in% p) %>%            # keep games that jon played
  summarise(pl = p[p != "jon"],       # get the name of the other player
            outcome = paste0(outcome[p=="jon"], "-", outcome[p!="jon"]))  # combine the scores (jon vs. other)

# # A tibble: 3 x 3
#   game_id pl    outcome
#     <int> <chr> <chr>  
# 1       1 joe   1-0    
# 2       2 james 0-1    
# 3       4 ken   0-1 

Предполагая, что вы можете изменить исходный набор данных один раз, в начале вы можете создать функцию, используя вторую часть:

GetSummaryStats = function(x) {
  dat2 %>%
    group_by(game_id) %>%              
    filter(x %in% p) %>%            
    summarise(pl = p[p != x],       
              outcome = paste0(outcome[p==x], "-", outcome[p!=x])) }

и назовите это так:

GetSummaryStats("jon")

для любого понравившегося вам игрока.

0 голосов
/ 10 ноября 2018

Это будет dplyr решение, которое позволяет проводить несколько игр между Джоном и другими игроками (не только одну игру). Он в основном фильтрует все игры, в которые входил Джон, и извлекает противника через mutate и ifelse. Затем он суммирует количество побед и поражений после группировки по противнику. В конце я вставляю общий результат для каждого оппонента и выбираю только этот вставленный столбец:

dat %>% mutate(p1 = as.character(p1), p2 = as.character(p2)) %>% 
  filter((p1 == "jon")|(p2 == "jon")) %>%
  mutate(opponent= ifelse(p1 == "jon",p2,p1)) %>% 
  group_by(opponent) %>%
  summarize(Wins = sum((outcome == "1-0" & p1 == "jon") | 
                       (outcome == "0-1" & p2 == "jon")) ,
            Losses = n() - Wins) %>%
  mutate(Outcome = paste(opponent, ": ",Wins, "-", Losses)) %>%
  select(Outcome)

Мне пришлось добавить мутацию as.character, чтобы правильно вернуть противников в ifelse. В противном случае переменные p1 и p2 все равно будут множителями, и вместо меток будут возвращаться числа (то есть имена игроков).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...