Comprendre la tuyauterie de dplyr et la fonction de synthèse

Aug 20 2020

Je cherche de l'aide pour comprendre la tuyauterie et résumer les fonctions à l'aide de dplyr. J'ai l'impression que mon codage est un peu verbeux et pourrait être simplifié. Il y a donc quelques questions ici parce que je sais qu'il me manque certains concepts, mais je ne sais pas trop où se situe ce manque de connaissances. J'ai inclus mon code complet en bas. Merci d'avance car c'est un peu plus demander.

1a. À partir des exemples de données ci-dessous et en utilisant dplyr, existe-t-il un moyen de calculer les matchs (dates) par équipe sans utiliser de table intermédiaire?

1b. J'ai inclus ma façon originale de calculer n_games qui n'a pas fonctionné. Pourquoi?

set.seed(123)
shot_df_ex <- tibble(Team_Name = sample(LETTERS[1:5],250, replace = TRUE),
                     Date = sample(as.Date(c("2019-08-01",
                                             "2019-09-01",
                                             "2018-08-01",
                                             "2018-09-01",
                                             "2017-08-01",
                                             "2017-09-01")), 
                                   size = 250, replace = TRUE),
                     Type = sample(c("shot","goal"), size = 250, 
                                   replace = TRUE, prob = c(0.9,0.1))
)

# count shots per team per game(date)
n_shots_per_game <- shot_df_ex %>% 
  count(Team_Name,Date)

n_shots_per_game

# count games (dates) per team [ISSUES!!!]
# is there a way to do this piping from the shot_df_ex tibble instead of 
#  using an intermediate tibble?

# count number of games using the tibble created above [DOES NOT WORK--WHY?]
n_games <- n_shots_per_game %>% 
  count(Team_Name)

n_games #what is this counting? It should be 6 for each.

# this works, but isn't count() just a quicker way to run
#  group_by() %>% summarise()? 
n_games <- n_shots_per_game %>% 
  group_by(Team_Name) %>% 
  summarise(N_Games=n())

n_games
  1. Voici mon processus de création d'un tableau récapitulatif. Je comprends que la tuyauterie vise à supprimer la création de certaines variables / tables intermédiaires. Où pourrais-je combiner les étapes ci-dessous pour créer la table finale avec un nombre minimum d'étapes intermédiaires.
# load librarys ------------------------------------------------
library(tidyverse)

# build sample shot data ---------------------------------------
set.seed(123)
shot_df_ex <- tibble(Team_Name = sample(LETTERS[1:5],250, replace = TRUE),
                     Date = sample(as.Date(c("2019-08-01",
                                             "2019-09-01",
                                             "2018-08-01",
                                             "2018-09-01",
                                             "2017-08-01",
                                             "2017-09-01")), 
                                   size = 250, replace = TRUE),
                     Type = sample(c("shot","goal"), size = 250, 
                                   replace = TRUE, prob = c(0.9,0.1))
)

# calculate data ----------------------------------------------
# since every row is a shot, the following function counts shots for ea. team
n_shots <- shot_df_ex %>% 
  count(Team_Name) %>% 
  rename(N_Shots = n)

n_shots

# do the same for goals for each team
n_goals <- shot_df_ex %>% 
  filter(Type == "goal") %>% 
  count(Team_Name,sort = T) %>% 
  rename(N_Goals = n) %>% 
  arrange(Team_Name)

n_goals

# count shots per team per game(date)
n_shots_per_game <- shot_df_ex %>% 
  count(Team_Name,Date)

n_shots_per_game

# count games (dates) per team [ISSUES!!!]
# is there a way to do this piping from the shot_df_ex tibble instead of 
#  using an intermediate tibble?

# count number of games using the tibble created above [DOES NOT WORK]
n_games <- n_shots_per_game %>% 
  count(Team_Name)

n_games #what is this counting? It should be 6 for each.

# this works, but isn't count() just a quicker way to run
#  group_by() %>% summarise()? 
n_games <- n_shots_per_game %>% 
  group_by(Team_Name) %>% 
  summarise(N_Games=n())

n_games

# combine data ------------------------------------------------
# combine columns and add average shots per game
shot_table_ex <- n_games %>% 
  left_join(n_shots) %>% 
  left_join(n_goals)

# final table with final average calculations
shot_table_ex <- shot_table_ex %>% 
  mutate(Shots_per_Game = round(N_Shots / N_Games, 1),
         Goals_per_Game = round(N_Goals / N_Games, 1)) %>% 
  arrange(Team_Name)

shot_table_ex

Réponses

1 stlba Aug 19 2020 at 23:25

Pour 1a, vous pouvez simplement passer directement de la fonction tibble () à count (). c'est à dire.

tibble(Team_Name = sample(LETTERS[1:5],250, replace = TRUE),
       Date = sample(as.Date(c("2019-08-01",
                               "2019-09-01",
                               "2018-08-01",
                               "2018-09-01",
                               "2017-08-01",
                               "2017-09-01")), 
                     size = 250, replace = TRUE),
       Type = sample(c("shot","goal"), size = 250, 
                     replace = TRUE, prob = c(0.9,0.1))) %>%
count(Team_Name,Date)

Dans 1b, count () utilise votre colonne n(c.-à-d. Le nombre de tirs) comme variable de pondération, donc additionne le nombre total de tirs par équipe, pas le nombre de lignes. Il imprime un message vous indiquant ceci:

Using `n` as weighting variable i Quiet this message with `wt = n` or count rows with `wt = 1`

L'utilisation count(Team_Name, wt=n())donnera le comportement que vous souhaitez.

Edit: partie 2

shot_table_ex <- tibble(Team_Name = sample(LETTERS[1:5],250, replace = TRUE),
                    Date = sample(as.Date(c("2019-08-01",
                                            "2019-09-01",
                                            "2018-08-01",
                                            "2018-09-01",
                                            "2017-08-01",
                                            "2017-09-01")), 
                                  size = 250, replace = TRUE),
                    Type = sample(c("shot","goal"), size = 250, 
                                  replace = TRUE, prob = c(0.9,0.1))) %>%
     group_by(Team_Name) %>%
     summarise(n_shots = n(),
               n_goals = sum(Type == "goal"),
               n_games = n_distinct(Date)) %>%
     mutate(Shots_per_Game = round(n_shots / n_games, 1),
            Goals_per_Game = round(n_goals / n_games, 1))
1 GenesRus Aug 19 2020 at 23:36

1a. À partir des exemples de données ci-dessous et en utilisant dplyr, existe-t-il un moyen de calculer les matchs (dates) par équipe sans utiliser de table intermédiaire?

Voici comment je le ferais:

shot_df_ex %>% 
  distinct(Team_Name, Date) %>% #Keeps only the cols given and one of each combo
  count(Team_Name)

Vous pouvez également utiliser unique:

shot_df_ex %>% 
  group_by(Team_Name) %>%
  summarize(N_Games = length(unique(Date))

1b. J'ai inclus ma façon originale de calculer n_games qui n'a pas fonctionné. Pourquoi?

Votre code fonctionne pour moi. Avez-vous peut-être économisé sur la table intermédiaire? Il compte les 6 attendus par équipe.

  1. Voici mon processus de création d'un tableau récapitulatif. Je comprends que la tuyauterie vise à supprimer la création de certaines variables / tables intermédiaires. Où pourrais-je combiner les étapes ci-dessous pour créer la table finale avec un nombre minimum d'étapes intermédiaires?
shot_df_ex %>% 
  group_by(Team_Name) %>% 
  summarize(
    N_Games = length(unique(Date)),
    N_Shots = sum(Type == "shot"),
    N_Goals = sum(Type == "goal")
  ) %>% 
  mutate(Shots_per_Game = round(N_Shots / N_Games, 1),
         Goals_per_Game = round(N_Goals / N_Games, 1))

Vous pouvez utiliser plusieurs étapes de synthèse à la fois tant que vous n'avez pas besoin de modifier votre regroupement. On profite ici (dans les sumappels) de l'interprétation de True comme 1 et False comme 0. lengthva bien sûr nous donner la longueur du vecteur produit par unique.

cela (count) fonctionne, mais count () n'est-il pas juste un moyen plus rapide d'exécuter group_by ()%>% summary ()?

countest juste une combinaison de group_by(col) %>% tally()et le décompte est essentiellement summarize(x=n())oui. :)