Использование суммирования dplyr для одного столбца, но с несколькими значениями параметров - PullRequest
0 голосов
/ 05 февраля 2019

Приносим извинения за непонятный заголовок (можно использовать справку) - надеюсь, приведенный ниже пример прояснит многое.У меня есть следующий фрейм данных результатов баскетбольного выстрела (1 строка == 1 баскетбольный выстрел):

> dput(zed)
structure(list(shooterTeamAlias = c("DUKE", "DUKE", "BC", "DUKE", 
"DUKE", "DUKE", "DUKE", "DUKE", "DUKE", "BC", "BC", "BC", "DUKE", 
"BC", "BC", "DUKE", "DUKE", "DUKE", "BC", "DUKE"), distanceCategory = c("sht2", 
"sht2", "sht3", "atr2", "mid2", "sht2", "lng3", "sht3", "atr2", 
"sht3", "sht3", "sht2", "mid2", "sht3", "sht3", "sht3", "atr2", 
"atr2", "sht2", "mid2"), eventType = c("twopointmiss", "twopointmade", 
"threepointmade", "twopointmade", "twopointmiss", "twopointmade", 
"threepointmiss", "threepointmiss", "twopointmade", "threepointmiss", 
"threepointmade", "twopointmiss", "twopointmade", "threepointmiss", 
"threepointmade", "threepointmiss", "twopointmade", "twopointmade", 
"twopointmade", "twopointmade")), row.names = c(NA, 20L), class = "data.frame")

> zed
   shooterTeamAlias distanceCategory      eventType
1              DUKE             sht2   twopointmiss
2              DUKE             sht2   twopointmade
3                BC             sht3 threepointmade
4              DUKE             atr2   twopointmade
5              DUKE             mid2   twopointmiss
6              DUKE             sht2   twopointmade
7              DUKE             lng3 threepointmiss
8              DUKE             sht3 threepointmiss
9              DUKE             atr2   twopointmade
10               BC             sht3 threepointmiss
11               BC             sht3 threepointmade
12               BC             sht2   twopointmiss
13             DUKE             mid2   twopointmade
14               BC             sht3 threepointmiss
15               BC             sht3 threepointmade
16             DUKE             sht3 threepointmiss
17             DUKE             atr2   twopointmade
18             DUKE             atr2   twopointmade
19               BC             sht2   twopointmade
20             DUKE             mid2   twopointmade

Этот фрейм данных в настоящее время имеет формат tidy-ish, и мне нужна команда group_by, а затем откормить ее большимвремя.Полные данные имеют 6 distanceCategories atr2, sht2, mid2, lng2, sht3, lng3 (пример выше имеет только 5), а также 2 категории, которые являются функцией других 6: all2 равно atr2, sht2, lng2, mid2, а all3 равно sht3, lng3.Тогда для каждой из этих 8 категорий я хотел бы получить столбец для марок, попыток, процентов и частоты попыток.Я использую столбец eventType, чтобы определить, был ли сделан выстрел.В настоящее время я делаю это со следующими

fat.data <- {zed %>%
    dplyr::group_by(shooterTeamAlias) %>%
    dplyr::summarise(

      shotsCount = n(),
      # Shooting By Distance Stats
      atr2Made = sum(distanceCategory == "atr2" & eventType == "twopointmade"),
      atr2Att = sum(distanceCategory == "atr2" & eventType %in% c("twopointmiss", "twopointmade")),
      atr2AttFreq = atr2Att / shotsCount,
      atr2Pct = ifelse(atr2Att > 0, atr2Made / atr2Att, 0),

      sht2Made = sum(distanceCategory == "sht2" & eventType == "twopointmade"),
      sht2Att = sum(distanceCategory == "sht2" & eventType %in% c("twopointmiss", "twopointmade")),
      sht2AttFreq = sht2Att / shotsCount, 
      sht2Pct = ifelse(sht2Att > 0, sht2Made / sht2Att, 0),

      mid2Made = sum(distanceCategory == "mid2" & eventType == "twopointmade"),
      mid2Att = sum(distanceCategory == "mid2" & eventType %in% c("twopointmiss", "twopointmade")),
      mid2AttFreq = mid2Att / shotsCount,
      mid2Pct = ifelse(mid2Att > 0, mid2Made / mid2Att, 0),

      lng2Made = sum(distanceCategory == "lng2" & eventType == "twopointmade"),
      lng2Att = sum(distanceCategory == "lng2" & eventType %in% c("twopointmiss", "twopointmade")),
      lng2AttFreq = lng2Att / shotsCount,
      lng2Pct = ifelse(lng2Att > 0, lng2Made / lng2Att, 0),

      all2Made = sum(atr2Made, sht2Made, mid2Made, lng2Made),
      all2Att = sum(atr2Att, sht2Att, mid2Att, lng2Att),
      all2AttFreq = all2Att / shotsCount,
      all2Pct = ifelse(all2Att > 0, all2Made / all2Att, 0),

      sht3Made = sum(distanceCategory == "sht3" & eventType == "threepointmade"),
      sht3Att = sum(distanceCategory == "sht3" & eventType %in% c("threepointmiss", "threepointmade")),
      sht3AttFreq = sht3Att / shotsCount,
      sht3Pct = ifelse(sht3Att > 0, sht3Made / sht3Att, 0),

      lng3Made = sum(distanceCategory == "lng3" & eventType == "threepointmade"),
      lng3Att = sum(distanceCategory == "lng3" & eventType %in% c("threepointmiss", "threepointmade")),
      lng3AttFreq = lng3Att / shotsCount,
      lng3Pct = ifelse(lng3Att > 0, lng3Made / lng3Att, 0),

      all3Made = sum(sht3Made, lng3Made),
      all3Att = sum(sht3Att, lng3Att),
      all3AttFreq = all3Att / shotsCount,
      all3Pct = ifelse(all3Att > 0, all3Made / all3Att, 0))}

... для 6 категорий, которые появляются в данных (все, кроме all2 и all3), все их 4 столбца вычисляются в одном и том жеманера.Как вы увидите для all2 и all3, расчеты немного отличаются.

В настоящее время не стоит беспокоиться о категориях all2 и all3, есть ли лучший способ для вычисления частоты появления, попытки, pct и попытки для 6 категорий в данных?Для 8 категорий * 4 типа столбцов == 32 столбца здесь все не так плохо, но у меня есть другой, похожий случай, когда у меня есть 21 категория * 4 типа столбцов, и мне приходится делать это несколько раз в своем коде.

Не уверен, что dplyr::group_by dplyr::summarise - мой лучший вариант (это то, чем я сейчас пользуюсь), или есть ли лучший способ сделать это.Улучшение этого кода / потенциальное ускорение его для моего проекта имеет решающее значение, и любая помощь приветствуется / я постараюсь не забыть щедро пожертвовать этот пост, даже если получу ответ в течение следующих 2 дней.

Редактировать !!!: Я только что понял, что сначала сгруппировать по distanceCategory, вычислить 4 статистики для каждой distanceCategory, а затем реструктурировать , чтобы dataframe в этот толстый формат мог бы быть проще ... это что-тоЯ сейчас работаю над вычислениями.Что-то вроде этого:

zed %>% 
  dplyr::group_by(shooterTeamAlias, distanceCategory) %>%
  dplyr::summarise(
    attempts = ...,
    makes = ...,
    pct = ...,
    attfreq = ...
  ) %>%
  tidyr::spread(...)

Спасибо !!

1 Ответ

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

Похоже, что это можно упростить, сгруппировав по distanceCategory, а затем применив одинаковую логику к каждому:

library(tidyverse)
zed %>%
  group_by(shooterTeamAlias, distanceCategory) %>%
  summarize(att = n(),   # n() counts how many rows in this group
            made = sum(eventType %>% str_detect("made"))
            pct = if_else(att > 0, made / att, 0)) %>%
  mutate(freq = att / sum(att))

# A tibble: 7 x 6
# Groups:   shooterTeamAlias [2]
  shooterTeamAlias distanceCategory   att  made   pct   freq
  <chr>            <chr>            <int> <int> <dbl>  <dbl>
1 BC               sht2                 2     1 0.5   0.286 
2 BC               sht3                 5     3 0.6   0.714 
3 DUKE             atr2                 4     4 1     0.308 
4 DUKE             lng3                 1     0 0     0.0769
5 DUKE             mid2                 3     2 0.667 0.231 
6 DUKE             sht2                 3     2 0.667 0.231 
7 DUKE             sht3                 2     0 0     0.154

Если вы хотите это в широком формате, вы можете сначала собрать приведенные выше вычисления, объединитьрасстояние со статистикой, а затем распределить по этому:

[same code as above] %>%
  gather(stat, value, -distanceCategory, -shooterTeamAlias) %>%
  unite(stat, distanceCategory, stat) %>%
  spread(stat, value)

# A tibble: 2 x 21
# Groups:   shooterTeamAlias [2]
  shooterTeamAlias atr2_att atr2_freq atr2_made atr2_pct lng3_att lng3_freq lng3_made lng3_pct mid2_att mid2_freq mid2_made mid2_pct sht2_att sht2_freq sht2_made sht2_pct sht3_att sht3_freq sht3_made sht3_pct
  <chr>               <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>     <dbl>    <dbl>
1 BC                     NA    NA            NA       NA       NA   NA             NA       NA       NA    NA            NA   NA            2     0.286         1    0.5          5     0.714         3      0.6
2 DUKE                    4     0.308         4        1        1    0.0769         0        0        3     0.231         2    0.667        3     0.231         2    0.667        2     0.154         0      0 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...