Сортировка значений по нескольким столбцам в R с помощью dplyr - PullRequest
0 голосов
/ 08 февраля 2019

Извините за не очень ясное название - надеюсь, что мой пример ниже поможет.Я работаю с некоторыми спортивными данными, пытаясь вычислить «статистику состава» для определенной группы игроков в данных.Ниже приведен пример типа данных, с которыми я работаю (playerInfo), а также тип анализа, который я пытаюсь выполнить (groupedInfo):

playerInfo = data.frame(
  lineup = c(1,2,3,4,5,6),
  player1 = c("Bil", "Tom", "Tom", "Nik", "Nik", "Joe"),
  player1id = c("e91", "a27", "a27", "b17", "b17", "3b3"),
  player2 = c("Nik", "Bil", "Nik", "Joe", "Tom", "Tom"),
  player2id = c("b17", "e91", "b17", "3b3", "a27", "a27"),
  player3 = c("Joe", "Joe", "Joe", "Tom", "Joe", "Nik"),
  player3id = c("3b3", "3b3", "3b3", "a27", "3b3", "b17"),
  points = c(6, 8, 3, 12, 36, 2),
  stringsAsFactors = FALSE
)

groupedInfo <- playerInfo %>%
  dplyr::group_by(player1, player2, player3) %>%
  dplyr::summarise(
    lineup_ct = n(),
    total_pts = sum(points)
  )

> groupedInfo
# A tibble: 6 x 5
# Groups:   player1, player2 [?]
  player1 player2 player3 lineup_ct total_pts
  <chr>   <chr>   <chr>       <int>     <dbl>
1 Bil     Nik     Joe             1         6
2 Joe     Tom     Nik             1         2
3 Nik     Joe     Tom             1        12
4 Nik     Tom     Joe             1        36
5 Tom     Bil     Joe             1         8
6 Tom     Nik     Joe             1         3

Цель состоит в том, чтобы group_by3 игрока в каждом ряду, а затем подсчитать некоторую сводную статистику (в этом простом примере - количество и сумма очков) для разных групп.К сожалению, в dplyr::group_by отсутствует тот факт, что определенные группы игроков должны быть одной и той же группой игроков, если одни и те же 3 игрока просто находятся в разных столбцах.

Например, в приведенном выше кадре данных все ряды 3, 4, 5, 6, 6 имеют одинаковых игроков (Ник, Том, Джо), однако, потому что иногда Ник - игрок1, а иногда Ник - игрок2 и т. Д.., group_by группирует их отдельно.

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

correctPlayerInfo = data.frame(
  lineup = c(1,2,3,4,5,6),
  player1 = c("Bil", "Bil", "Joe", "Joe", "Joe", "Joe"),
  player1id = c("e91", "e91", "3b3", "3b3", "3b3", "3b3"),
  player2 = c("Joe", "Joe", "Nik", "Nik", "Nik", "Nik"),
  player2id = c("3b3", "3b3", "b17", "b17", "b17", "b17"),
  player3 = c("Nik", "Tom", "Tom", "Tom", "Tom", "Tom"),
  player3id = c("b17", "a27", "a27", "a27", "a27", "a27"),
  points = c(6, 8, 3, 12, 36, 2),
  stringsAsFactors = FALSE
)

correctGroupedInfo <- correctPlayerInfo %>%
  dplyr::group_by(player1, player2, player3) %>%
  dplyr::summarise(
    lineup_ct = n(),
    total_pts = sum(points)
  )

> correctGroupedInfo
# A tibble: 3 x 5
# Groups:   player1, player2 [?]
  player1 player2 player3 lineup_ct total_pts
  <chr>   <chr>   <chr>       <int>     <dbl>
1 Bil     Joe     Nik             1         6
2 Bil     Joe     Tom             1         8
3 Joe     Nik     Tom             4        53

Во втором примере я вручную отсортировал данные в алфавитном порядке, так что player1

Как мне достичь этого программным путем?Я не уверен, является ли (а) реструктуризация playerInfo в отсортированном по столбцам correctPlayerInfo (как я сделал выше (), или (b) какой-то другой подход, где group_by автоматически определяет, что это те же группы, лучше всего).

Я активно работаю над этим и буду публиковать обновления, если смогу найти свое собственное решение. До тех пор любая помощь с этим очень ценится!

Редактировать: До сих пор я пробовал что-то вроде этого:

newPlayerInfo <- playerInfo %>%
  dplyr::mutate(newPlayer1 = min(player1, player2, player3)) %>%
  dplyr::mutate(newPlayer3 = max(player1, player2, player3))

... безрезультатно.

1 Ответ

0 голосов
/ 08 февраля 2019

Вы можете создать групповые идентификаторы, которые будут сортировать составные имена игроков (или идентификаторы).Например:

playerInfo %>% 
  mutate(
    group_id = purrr::pmap_chr(
      .l = list(p1 = player1, p2 = player2, p3 = player3),
      .f = function(p1, p2, p3) paste(sort(c(p1, p2, p3)), collapse = "_")
    )
  ) %>% 
  group_by(group_id) %>% 
  summarise(
    lineup_ct = n(),
    total_pts = sum(points)
  )

# A tibble: 3 x 3
  group_id    lineup_ct total_pts
  <chr>           <int>     <dbl>
1 Bil_Joe_Nik         1         6
2 Bil_Joe_Tom         1         8
3 Joe_Nik_Tom         4        53
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...