การทำความเข้าใจเกี่ยวกับการวางท่อ dplyr และฟังก์ชันการสรุป
ฉันกำลังมองหาความช่วยเหลือในการทำความเข้าใจการวางท่อและการสรุปฟังก์ชันโดยใช้ 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
- ด้านล่างนี้คือขั้นตอนการสร้างตารางสรุป ฉันเข้าใจว่าการวางท่อมีไว้เพื่อตัดการสร้างตัวแปร / ตารางระดับกลางออกไป ฉันจะรวมขั้นตอนด้านล่างเพื่อสร้างตารางสุดท้ายโดยมีขั้นตอนกลางขั้นต่ำได้ที่ไหน
# 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
คำตอบ
สำหรับ 1a คุณสามารถไปป์ตรงจากฟังก์ชัน tibble () เพื่อนับ () กล่าวคือ.
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))
1a. จากข้อมูลตัวอย่างด้านล่างและการใช้ dplyr มีวิธีคำนวณเกม (วันที่) ต่อทีมโดยไม่ต้องใช้ตารางกลางหรือไม่?
นี่คือวิธีที่ฉันจะทำ:
shot_df_ex %>%
distinct(Team_Name, Date) %>% #Keeps only the cols given and one of each combo
count(Team_Name)
คุณยังสามารถใช้ unique:
shot_df_ex %>%
group_by(Team_Name) %>%
summarize(N_Games = length(unique(Date))
1b. ฉันได้รวมวิธีเดิมของฉันในการคำนวณ n_games ซึ่งใช้ไม่ได้ ทำไม?
รหัสของคุณใช้งานได้สำหรับฉัน คุณอาจบันทึกผ่านตารางกลางหรือไม่? มันจะนับ 6 ที่คาดหวังต่อทีม
- ด้านล่างนี้คือขั้นตอนการสร้างตารางสรุป ฉันเข้าใจว่าการวางท่อมีไว้เพื่อตัดการสร้างตัวแปร / ตารางระดับกลางออกไป ฉันจะรวมขั้นตอนด้านล่างเพื่อสร้างตารางสุดท้ายกับขั้นตอนกลางขั้นต่ำได้ที่ไหน
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
สาย) ของการตีความของทรูเป็นที่ 1 และเป็นเท็จ 0. ประสงค์ของหลักสูตรให้เราความยาวของเวกเตอร์ที่ผลิตโดยlength
unique
สิ่งนี้ (count) ใช้งานได้ แต่ไม่นับ () เป็นเพียงวิธีที่เร็วกว่าในการเรียกใช้ group_by ()%>% สรุป ()?
count
เป็นเพียงการรวมgroup_by(col) %>% tally()
และการนับเป็นหลักsummarize(x=n())
ใช่ :)