dplyrの配管と要約機能を理解する

Aug 20 2020

dplyrを使用して配管を理解し、関数を要約するためのヘルプを探しています。私のコーディングは少し冗長で、単純化できると思います。いくつかの概念が欠けていることはわかっているので、ここにいくつか質問がありますが、その知識の欠如がどこにあるのかよくわかりません。一番下に完全なコードを含めました。これは少し大きい質問なので、事前に感謝します。

1a。以下のデータ例とdplyrを使用して、中間テーブルを使用せずにチームごとのゲーム(日付)を計算する方法はありますか?

1b。動作しなかったn_gamesを計算するための独自の方法を含めました。どうして?

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. 以下は、要約テーブルを作成する私のプロセスです。パイピングは、いくつかの中間変数/テーブルの作成を削減することを目的としていることを理解しています。以下のステップをどこで組み合わせて、最小数の中間ステップでファイナルテーブルを作成できますか。
# 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

回答

1 stlba Aug 19 2020 at 23:25

1aの場合、tibble()関数からcount()に直接パイプすることができます。すなわち。

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)

1bでは、count()は列n(つまり、ショット数)を重み変数として使用しているため、行数ではなく、チームごとのショットの総数を合計しています。これを伝えるメッセージを出力します。

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

を使用count(Team_Name, wt=n())すると、必要な動作が得られます。

編集:パート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。以下のデータ例とdplyrを使用して、中間テーブルを使用せずにチームごとのゲーム(日付)を計算する方法はありますか?

これは私がそれをする方法です:

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

一意のものを使用することもできます。

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

1b。動作しなかったn_gamesを計算するための独自の方法を含めました。どうして?

あなたのコードは私のために働いています。おそらく中間テーブルを保存しましたか?チームごとに予想される6を数えています。

  1. 以下は、要約テーブルを作成する私のプロセスです。パイピングは、いくつかの中間変数/テーブルの作成を削減することを目的としていることを理解しています。以下のステップをどこで組み合わせて、最小数の中間ステップでファイナルテーブルを作成できますか?
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))

グループ化を変更する必要がない限り、一度に複数の要約ステップを使用できます。ここでは(sum呼び出しで)Trueを1として、Falseを0として解釈することを利用しています。lengthもちろん、によって生成されるベクトルの長さがわかりuniqueます。

この(count)は機能しますが、count()はgroup_by()%>%summarise()を実行するためのより速い方法ではありませんか?

countは単なる組み合わせでgroup_by(col) %>% tally()あり、集計は本質的summarize(x=n())にそうです。:)