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))

그룹화를 변경할 필요가없는 한 한 번에 여러 요약 단계를 사용할 수 있습니다. 우리는 여기에서 sumTrue를 1로, False를 0으로 해석 하는 것을 활용하고 있습니다. length물론에서 생성 된 벡터의 길이를 제공 할 것입니다 unique.

이 (count)는 작동하지만 count ()는 group_by () %> % summarise ()를 실행하는 더 빠른 방법이 아닙니까?

count의 조합 일 group_by(col) %>% tally()뿐이고 집계는 본질적으로 summarize(x=n())그렇습니다. :)