ฟังก์ชันการรวมข้อมูลใน R: summarise() และ group_by() ตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

ฟังก์ชัน Aggregate ใน R ที่ใช้ไลบรารี dplyr จะรวมข้อมูลหลายแถวเข้าเป็นสถิติเดียวต่อกลุ่ม บทช่วยสอนนี้จะใช้ฟังก์ชัน group_by() ร่วมกับ summarise() กับข้อมูลการตีของ Lahman เพื่อคำนวณค่าเฉลี่ย ผลรวม ค่าเบี่ยงเบนมาตรฐาน จำนวน และค่าตำแหน่งต่างๆ จากข้อมูลทั้งหมด 104,324 รายการ

  • 🧮 คำกริยาหลัก: summarise(df, name = function(column)) จะคืนค่าแถวเดียว จากนั้น group_by() จะแปลงแถวนั้นให้เป็นแถวเดียวต่อกลุ่มก่อน
  • 📊 กลุ่มสถิติ: ค่าเฉลี่ยและค่ามัธยฐานอธิบายจุดศูนย์กลาง ค่าเบี่ยงเบนมาตรฐานและช่วงควาร์ไทล์อธิบายการกระจายตัว และค่าต่ำสุดและค่าสูงสุดอธิบายช่วงพิสัย
  • 🔢 นับ: n() นับจำนวนแถวในกลุ่มปัจจุบัน และ n_distinct() นับจำนวนค่าที่ไม่ซ้ำกันภายในกลุ่มนั้น
  • 📍 คำช่วยกำหนดตำแหน่ง: first(), last() และ nth() ตัวอย่างเช่นtracข้อสังเกตเฉพาะจากแต่ละกลุ่ม
  • 🔄 งานแบบหลายคอลัมน์: ฟังก์ชัน `across()` ใช้ฟังก์ชันเดียวกับหลายคอลัมน์โดยไม่ต้องเขียนโค้ดซ้ำสำหรับแต่ละคอลัมน์
  • 🔓 กลุ่มping สุขอนามัย: ควรเรียกใช้ ungroup() ก่อนทำการคำนวณใดๆ ที่ต้องประมวลผลข้อมูลทั้งตารางอีกครั้งเสมอ

ฟังก์ชันรวม R

ชุดข้อมูลที่ใช้ในบทช่วยสอนนี้

การสรุปค่าตัวแปรจะช่วยให้คุณเข้าใจข้อมูลในเบื้องต้น และการสรุปค่าตามกลุ่มจะช่วยให้คุณเข้าใจการกระจายตัวของค่าต่างๆ ได้ดียิ่งขึ้น บทช่วยสอนนี้จะแสดงวิธีการรวมชุดข้อมูลตามกลุ่มโดยใช้ไลบรารี dplyr

บทช่วยสอนนี้ใช้ชุดข้อมูลการตีลูกของ Lahman หลังจากนำเข้าและเก็บรักษาข้อมูลแล้วping เฉพาะคอลัมน์ทั้งเก้าที่ระบุไว้ด้านล่างนี้ เฟรมข้อมูลที่ใช้งานอยู่ประกอบด้วยข้อมูลสังเกตการณ์ 104,324 รายการ และตัวแปร 9 ตัว:

  • playerID: รหัสประจำตัวผู้เล่น ปัจจัย
  • รหัสปี: ปี ปัจจัย
  • รหัสทีม: ทีม. ปัจจัย
  • lgID: ลีก. ปัจจัย: AA อัล ชั้น NL PL UA
  • AB: ที่ค้างคาว ตัวเลข
  • G: เกม: จำนวนเกมโดยผู้เล่น ตัวเลข
  • ร: วิ่ง ตัวเลข
  • HR: โฮมรัน ตัวเลข
  • SH: การสังเวยเพลงฮิต. ตัวเลข

ก่อนที่จะทำการสรุป คุณจะต้องดำเนินการตามขั้นตอนต่อไปนี้เพื่อเตรียมข้อมูล:

  • ขั้นตอนที่ 1: นำเข้าข้อมูล
  • ขั้นตอนที่ 2: เลือกตัวแปรที่เกี่ยวข้อง
  • ขั้นตอนที่ 3: จัดเรียงข้อมูล
library(dplyr)

# Step 1
data <- read.csv("https://raw.githubusercontent.com/guru99-edu/R-Programming/master/lahman-batting.csv") %>%

# Step 2
select(c(playerID, yearID, AB, teamID, lgID, G, R, HR, SH))  %>% 

# Step 3
arrange(playerID, teamID, yearID)

แนวปฏิบัติที่ดีเมื่อคุณนำเข้าชุดข้อมูลคือการใช้ฟังก์ชัน glimpse() เพื่อให้ทราบแนวคิดเกี่ยวกับโครงสร้างของชุดข้อมูล

# Structure of the data
glimpse(data)

Output:

Observations: 104,324
Variables: 9
$ playerID <fctr> aardsda01, aardsda01, aardsda01, aardsda01, aardsda01, a...
$ yearID   <int> 2015, 2008, 2007, 2006, 2012, 2013, 2009, 2010, 2004, 196...
$ AB       <int> 1, 1, 0, 2, 0, 0, 0, 0, 0, 603, 600, 606, 547, 516, 495, ...
$ teamID   <fctr> ATL, BOS, CHA, CHN, NYA, NYN, SEA, SEA, SFN, ATL, ATL, A...
$ lgID     <fctr> NL, AL, AL, NL, AL, NL, AL, AL, NL, NL, NL, NL, NL, NL, ...
$ G        <int> 33, 47, 25, 45, 1, 43, 73, 53, 11, 158, 155, 160, 147, 15...
$ R        <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 113, 84, 100, 103, 95, 75...
$ HR       <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 39, 29, 44, 38, 47, 34, 40...
$ SH       <int> 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, ...

สรุป()

รูปแบบโครงสร้างของ summarise() เป็นแบบพื้นฐานและสอดคล้องกับคำกริยาอื่นๆ ที่รวมอยู่ในไลบรารี dplyr

summarise(df, variable_name=condition) 
arguments: 
- `df`: Dataset used to construct the summary statistics 
- `variable_name=condition`: Formula to create the new variable

ดูรหัสด้านล่าง:

summarise(data, mean_run =mean(R))

Code คำอธิบาย

  • summarise(data, mean_run = mean(R)): สร้างตัวแปรชื่อ mean_run ซึ่งเป็นค่าเฉลี่ยของคอลัมน์ที่รันจากข้อมูลชุดข้อมูล

Output:

##   mean_run
## 1 19.20114

คุณสามารถเพิ่มตัวแปรได้มากเท่าที่คุณต้องการ โดยจะคืนค่าเกมเฉลี่ยที่เล่นและค่าเสียสละเฉลี่ย

summarise(data, mean_games = mean(G),
    mean_SH = mean(SH, na.rm = TRUE))

Code คำอธิบาย

  • mean_SH = mean(SH, na.rm = TRUE): สรุปค่าตัวแปรที่สอง คุณตั้งค่า na.rm = TRUE เนื่องจากคอลัมน์ SH มีข้อสังเกตที่ขาดหายไป

Output:

##   mean_games  mean_SH
## 1   51.98361 2.340085

group_by() กับ ไม่ใช้ group_by()

เมื่อใช้ summarise() เพียงอย่างเดียว จะยุบข้อมูลทั้งเฟรมให้เหลือเพียงแถวเดียว ดังตัวอย่างข้างต้น แต่พลังที่แท้จริงของมันจะปรากฏขึ้นเมื่อคุณเพิ่ม group_by() เข้าไป: ดีพลีร์ จากนั้นไลบรารีจะนำการคำนวณเดียวกันไปใช้แยกกันในแต่ละกลุ่ม และส่งคืนข้อมูลหนึ่งแถวต่อกลุ่ม

โปรดทราบว่า group_by ทำงานได้อย่างสมบูรณ์แบบกับคำกริยาอื่นๆ ทั้งหมด (เช่น mutate(), filter(), Arrange(), …)

การใช้ตัวดำเนินการท่อจะสะดวกในกรณีที่คุณมีขั้นตอนมากกว่าหนึ่งขั้นตอน คุณสามารถคำนวณโฮมรันเฉลี่ยตามลีกเบสบอลได้

data %>%
	group_by(lgID) %>%
	summarise(mean_run = mean(HR))

Code คำอธิบาย

  • data: ชุดข้อมูลที่ใช้สร้างสถิติสรุป
  • group_by(lgID): แบ่งข้อมูลตามค่า lgID ก่อนทำการสรุปผล
  • สรุป (mean_run = mean (HR)): คำนวณโฮมรันเฉลี่ย

Output:

## 
# A tibble: 7 x 2
##     lgID  mean_run
##   <fctr>     <dbl>
## 1     AA 0.9166667
## 2     AL 3.1270988
## 3     FL 1.3131313
## 4     NL 2.8595953
## 5     PL 2.5789474
## 6     UA 0.6216216
## 7   <NA> 0.2867133	

คำสั่ง pipe สามารถใช้งานร่วมกับ ggplot() ได้เช่นกัน ดังนั้นกระบวนการทั้งหมดตั้งแต่ข้อมูลดิบไปจนถึงแผนภูมิที่เสร็จสมบูรณ์จึงอยู่ในคำสั่งเดียว โค้ดด้านล่างนี้รวม group_by(), summarise() และ ggplot() เพื่อแสดงค่าเฉลี่ยโฮมรันต่อลีกในรูปแบบแผนภูมิแท่ง

คุณจะดำเนินการตามขั้นตอนต่อไปนี้:

  • ขั้นตอนที่ 1: เลือกกรอบข้อมูล
  • ขั้นตอนที่ 2: จัดกลุ่มข้อมูล
  • ขั้นตอนที่ 3: สรุปข้อมูล
  • ขั้นตอนที่ 4: พล็อตสถิติสรุป
library(ggplot2)
# Step 1
data %>% 
#Step 2
group_by(lgID) %>% 
#Step 3
summarise(mean_home_run = mean(HR)) %>% 
#Step 4
ggplot(aes(x = lgID, y = mean_home_run, fill = lgID)) +
    geom_bar(stat = "identity") +
    theme_classic() +
    labs(
        x = "baseball league",
        y = "Average home run",
        title = paste(
            "Example group_by() with summarise()"
        )
    )

Output:

ตัวอย่าง Group_by พร้อมสรุป

ฟังก์ชันที่คุณสามารถใช้ภายใน summarise()

กริยา summarise() เข้ากันได้กับฟังก์ชันเกือบทั้งหมดใน R ต่อไปนี้คือรายการฟังก์ชันที่มีประโยชน์สั้นๆ ที่คุณสามารถใช้ร่วมกับ summarise():

วัตถุประสงค์ ฟังก์ชัน Descriptไอออน
ขั้นพื้นฐาน หมายถึง() ค่าเฉลี่ยของเวกเตอร์ x
ค่ามัธยฐาน () ค่ามัธยฐานของเวกเตอร์ x
ผลรวม () ผลรวมของเวกเตอร์ x
การเปลี่ยนแปลง เอสดี() ค่าเบี่ยงเบนมาตรฐานของเวกเตอร์ x
ไอคิวอาร์() อินเทอร์ควอไทล์ของเวกเตอร์ x
พิสัย นาที() ขั้นต่ำของเวกเตอร์ x
สูงสุด () สูงสุดของเวกเตอร์ x
ปริมาณ() ควอไทล์ของเวกเตอร์ x
ตำแหน่ง แรก() ใช้กับ group_by() การสังเกตครั้งแรกของกลุ่ม
ล่าสุด() ใช้กับ group_by() การสังเกตครั้งสุดท้ายของกลุ่ม
ที่ n() ใช้กับ group_by() การสังเกตครั้งที่ n ของกลุ่ม
นับ เอ็น() ใช้กับ group_by() นับจำนวนแถว
n_แตกต่าง() ใช้กับ group_by() นับจำนวนการสังเกตที่แตกต่างกัน

ส่วนด้านล่างนี้จะอธิบายตัวอย่างการใช้งานแต่ละฟังก์ชันในตารางด้านบน หากคุณยังไม่คุ้นเคยกับการใช้เครื่องหมายไปป์ (pipe) และคำกริยาอื่นๆ โปรดเริ่มต้นจากส่วนแรก คู่มือการเลือก การกรอง และการจัดเรียง.

ฟังก์ชั่นพื้นฐาน

ในตัวอย่างก่อนหน้านี้ คุณไม่ได้จัดเก็บสถิติสรุปไว้ในกรอบข้อมูล

คุณสามารถสร้าง data frame จากข้อมูลสรุปได้ในสองขั้นตอน:

  • ขั้นตอนที่ 1: จัดเก็บ data frame เพื่อใช้งานต่อไป
  • ขั้นตอนที่ 2: ใช้ชุดข้อมูลเพื่อสร้างการลงจุดเส้น

ขั้นตอน 1) คุณคำนวณจำนวนเกมเฉลี่ยที่เล่นในแต่ละปี

## Mean
ex1 <- data %>%
	group_by(yearID) %>%
	summarise(mean_game_year = mean(G))
head(ex1)

Code คำอธิบาย

  • สถิติสรุปของชุดข้อมูลการตีถูกจัดเก็บไว้ใน data frame ex1

Output:

## # A tibble: 6 x 2
##   yearID mean_game_year
##    <int>          <dbl>
## 1   1871       23.42308
## 2   1872       18.37931
## 3   1873       25.61538
## 4   1874       39.05263
## 5   1875       28.39535
## 6   1876       35.90625	

ขั้นตอน 2) คุณแสดงสถิติสรุปด้วยการวาดเส้นและดูแนวโน้ม

# Plot the graph
ggplot(ex1, aes(x = yearID, y = mean_game_year)) +
    geom_line() +
    theme_classic() +
    labs(
        x = "Year",
        y = "Average games played",
        title = paste(
            "Average games played from 1871 to 2016"
        )
    )

Output:

ตัวอย่างฟังก์ชั่นพื้นฐาน

เซตย่อย

ฟังก์ชัน summarise() สามารถทำงานร่วมกับการตั้งค่าย่อยได้

## Subsetting + Median
data %>%
group_by(lgID) %>%
summarise(median_at_bat_league = median(AB), 
	#Compute the median without the zero 
	median_at_bat_league_no_zero = median(AB[AB > 0]))

Code คำอธิบาย

  • median_at_bat_league_no_zero = ค่ามัธยฐาน (AB[AB > 0]): ตัวแปร AB มี 0 จำนวนมาก คุณสามารถเปรียบเทียบค่ามัธยฐานของ ที่ค้างคาว ตัวแปรที่มีและไม่มี 0

Output:

## # A tibble: 7 x 3
##     lgID median_at_bat_league median_at_bat_league_no_zero
##   <fctr>                <dbl>                        <dbl>
## 1     AA                  130                          131
## 2     AL                   38                           85
## 3     FL                   88                           97
## 4     NL                   56                           67
## 5     PL                  238                          238
## 6     UA                   35                           35
## 7   <NA>                  101                          101	

รวม

ฟังก์ชั่นที่มีประโยชน์อีกอย่างในการรวมตัวแปรคือ sum()

คุณสามารถตรวจสอบว่าลีกใดมีโฮมรันมากกว่า

## Sum
data %>%
	group_by(lgID) %>%
	summarise(sum_homerun_league = sum(HR))

Output:

## # A tibble: 7 x 2
##     lgID sum_homerun_league
##   <fctr>              <int>
## 1     AA                341
## 2     AL              29426
## 3     FL                130
## 4     NL              29817
## 5     PL                 98
## 6     UA                 46
## 7   <NA>                 41	

ส่วนเบี่ยงเบนมาตรฐาน

การแพร่กระจายในข้อมูลคำนวณด้วยค่าเบี่ยงเบนมาตรฐานหรือ sd() ใน R

# Spread
data %>%
	group_by(teamID) %>%
	summarise(sd_at_bat_league = sd(HR))

Output:

## # A tibble: 148 x 2
##    teamID sd_at_bat_league
##    <fctr>            <dbl>
##  1    ALT               NA
##  2    ANA        8.7816395
##  3    ARI        6.0765503
##  4    ATL        8.5363863
##  5    BAL        7.7350173
##  6    BFN        1.3645163
##  7    BFP        0.4472136
##  8    BL1        0.6992059
##  9    BL2        1.7106757
## 10    BL3        1.0000000
## # ... with 138 more rows		

ความแตกต่างของจำนวนโฮมรันระหว่างทีมนั้นค่อนข้างมาก และ ALT ส่งคืนค่า NA เนื่องจากทีมนั้นมีเพียงแถวเดียว จึงไม่สามารถคำนวณค่าเบี่ยงเบนมาตรฐานได้

ขั้นต่ำและสูงสุด

คุณสามารถเข้าถึงค่าต่ำสุดและค่าสูงสุดของเวกเตอร์ได้ด้วยฟังก์ชัน min() และ max()

โค้ดด้านล่างนี้ส่งคืนจำนวนเกมสูงสุดและต่ำสุดในหนึ่งฤดูกาลที่เล่นโดยผู้เล่น

# Min and max
data %>%
	group_by(playerID) %>%
	summarise(min_G = min(G),
    max_G = max(G))

Output:

## # A tibble: 10,395 x 3
##     playerID min_G max_G
##       <fctr>       <int>
##  1 aardsda01    53    73
##  2 aaronha01   120   156
##  3  aasedo01    24    66
##  4  abadfe01    18    18
##  5 abadijo01    11    11
##  6 abbated01     3   153
##  7 abbeybe01    11    11
##  8 abbeych01    80   132
##  9 abbotgl01     5    23
## 10 abbotji01    13    29
## # ... with 10,385 more rows

นับ

การนับจำนวนข้อมูลต่อกลุ่มนั้นเป็นสิ่งที่ควรทำเสมอ ใน R ฟังก์ชัน n() จะส่งคืนจำนวนแถวในกลุ่มปัจจุบัน

ตัวอย่างเช่นโค้ดด้านล่างนี้จะคำนวณจำนวนปีที่เล่นโดยผู้เล่นแต่ละคน

# count observations
data %>%
	group_by(playerID) %>%
	summarise(number_year = n()) %>%
	arrange(desc(number_year))

Output:

## # A tibble: 10,395 x 2
##     playerID number_year
##       <fctr>       <int>
##  1 pennohe01          11
##  2 joosted01          10
##  3 mcguide01          10
##  4  rosepe01          10
##  5 davisha01           9
##  6 johnssi01           9
##  7  kaatji01           9
##  8 keelewi01           9
##  9 marshmi01           9
## 10 quirkja01           9
## # ... with 10,385 more rows

ครั้งแรกและครั้งสุดท้าย

คุณสามารถเลือกตำแหน่งแรก สุดท้าย หรือตำแหน่งที่ n ของกลุ่มได้

ตัวอย่างเช่น คุณสามารถค้นหาปีแรกและปีสุดท้ายของผู้เล่นแต่ละคนได้

# first and last
data %>%
	group_by(playerID) %>%
	summarise(first_appearance = first(yearID),
		last_appearance = last(yearID))

Output:

## # A tibble: 10,395 x 3
##     playerID first_appearance last_appearance
##       <fctr>            <int>           <int>
##  1 aardsda01             2009            2010
##  2 aaronha01             1973            1975
##  3  aasedo01             1986            1990
##  4  abadfe01             2016            2016
##  5 abadijo01             1875            1875
##  6 abbated01             1905            1897
##  7 abbeybe01             1894            1894
##  8 abbeych01             1895            1897
##  9 abbotgl01             1973            1979
## 10 abbotji01             1992            1996
## # ... with 10,385 more rows

การสังเกตครั้งที่ n

ฟังก์ชัน nth() เป็นฟังก์ชันเสริมของ first() และ last() โดยจะส่งคืนค่าสังเกตการณ์ที่ดัชนีที่คุณป้อนภายในแต่ละกลุ่ม

ตัวอย่างเช่น คุณสามารถกรองเฉพาะปีที่สองที่ทีมเล่นได้

# nth
data %>%
	group_by(teamID) %>%
	summarise(second_game = nth(yearID, 2)) %>%
	arrange(second_game)

Output:

## # A tibble: 148 x 2
##    teamID second_game
##    <fctr>       <int>
##  1    BS1        1871
##  2    CH1        1871
##  3    FW1        1871
##  4    NY2        1871
##  5    RC1        1871
##  6    BR1        1872
##  7    BR2        1872
##  8    CL1        1872
##  9    MID        1872
## 10    TRO        1872
## # ... with 138 more rows

จำนวนการสังเกตที่แตกต่างกัน

n() จะส่งคืนจำนวนแถวในกลุ่มปัจจุบัน ส่วน n_distinct() ที่เกี่ยวข้องนั้นจะนับค่าที่ไม่ซ้ำกันแทน

ในตัวอย่างถัดไป คุณจะบวกจำนวนผู้เล่นทั้งหมดที่ทีมคัดเลือกระหว่างช่วงเวลาทั้งหมด

# distinct values
data %>%
	group_by(teamID) %>%
	summarise(number_player = n_distinct(playerID)) %>%
	arrange(desc(number_player))

Code คำอธิบาย

  • group_by(teamID): จัดกลุ่มตามทีม
  • สรุป(จำนวนผู้เล่น = n_แตกต่าง(playerID)): นับจำนวนผู้เล่นที่ไม่ซ้ำกันในแต่ละทีม
  • Arrange(desc(number_player)): จัดเรียงข้อมูลตามจำนวนผู้เล่น

Output:

## # A tibble: 148 x 2
##    teamID number_player
##    <fctr>         <int>
##  1    CHN           751
##  2    SLN           729
##  3    PHI           699
##  4    PIT           683
##  5    CIN           679
##  6    BOS           647
##  7    CLE           646
##  8    CHA           636
##  9    DET           623
## 10    NYA           612
## # ... with 138 more rows

หลายกลุ่ม

สถิติสรุปสามารถรับรู้ได้ในหลายกลุ่ม

# Multiple groups
data %>%
	group_by(yearID, teamID) %>%
	summarise(mean_games = mean(G)) %>%
	arrange(desc(teamID, yearID))

Code คำอธิบาย

  • group_by(yearID, teamID): จัดกลุ่มตามปี และ ทีม
  • summarise(mean_games = mean(G)): หาค่าเฉลี่ยของจำนวนเกมที่เล่น
  • Arrange(desc(teamID, yearID)): จัดเรียงข้อมูลตามทีมและปี

Output:

## # A tibble: 2,829 x 3
## # Groups:   yearID [146]
##    yearID teamID mean_games
##     <int> <fctr>      <dbl>
##  1   1884    WSU   20.41667
##  2   1891    WS9   46.33333
##  3   1886    WS8   22.00000
##  4   1887    WS8   51.00000
##  5   1888    WS8   27.00000
##  6   1889    WS8   52.42857
##  7   1884    WS7    8.00000
##  8   1875    WS6   14.80000
##  9   1873    WS5   16.62500
## 10   1872    WS4    4.20000
## # ... with 2,819 more rows

ตัวกรอง

ก่อนที่คุณจะดำเนินการใดๆ คุณสามารถกรองชุดข้อมูลได้ ชุดข้อมูลเริ่มต้นในปี พ.ศ. 1871 และการวิเคราะห์ไม่จำเป็นต้องมีปีก่อนหน้า พ.ศ. 1980

# Filter
data %>%
	filter(yearID > 1980) %>%
	group_by(yearID) %>%
	summarise(mean_game_year = mean(G))

Code คำอธิบาย

  • filter(yearID > 1980): กรองข้อมูลเพื่อแสดงเฉพาะปีที่เกี่ยวข้อง (เช่น หลังปี 1980)
  • group_by(yearID): จัดกลุ่มตามปี
  • summarise(mean_game_year = mean(G)): สรุปข้อมูล

Output:

## # A tibble: 36 x 2
##    yearID mean_game_year
##     <int>          <dbl>
##  1   1981       40.64583
##  2   1982       56.97790
##  3   1983       60.25128
##  4   1984       62.97436
##  5   1985       57.82828
##  6   1986       58.55340
##  7   1987       48.74752
##  8   1988       52.57282
##  9   1989       58.16425
## 10   1990       52.91556
## # ... with 26 more rows

ยกเลิกการจัดกลุ่ม

สุดท้าย คุณต้องกำจัดดินเหนียวออกไปping ก่อนที่จะเปลี่ยนระดับที่ใช้ในการคำนวณ หากไม่มี ungroup() ฟังก์ชัน summarise() ตัวที่สองจะยังคงทำงานแยกตามผู้เล่นแต่ละคน

# Ungroup the data
data %>%
	filter(HR > 0) %>%
	group_by(playerID) %>%
	summarise(average_HR_game = sum(HR) / sum(G)) %>%
	ungroup() %>%
	summarise(total_average_homerun = mean(average_HR_game))

Code คำอธิบาย

  • filter(HR >0) : ไม่รวมโฮมรันเป็นศูนย์
  • group_by (playerID): จัดกลุ่มตามผู้เล่น
  • สรุป (ค่าเฉลี่ย_HR_game = ผลรวม (HR) / ผลรวม (G)): คำนวณโฮมรันเฉลี่ยตามผู้เล่น
  • ungroup(): ลบกลุ่มออกping
  • summarise(total_average_homerun = mean(average_HR_game)): สรุปข้อมูล

Output:

## # A tibble: 1 x 1
##   total_average_homerun
##                   <dbl>
## 1            0.06882226	

วิธีสรุปข้อมูลจากหลายคอลัมน์ด้วยฟังก์ชัน across()

ตัวอย่างข้างต้นทั้งหมดระบุชื่อคอลัมน์ทีละคอลัมน์ เมื่อต้องการสถิติเดียวกันสำหรับหลายคอลัมน์ ฟังก์ชัน across() จะนำสถิตินั้นไปใช้กับทุกคอลัมน์ในการเรียกเพียงครั้งเดียว

# One function, several columns
data %>%
    group_by(lgID) %>%
    summarise(across(c(R, HR, G), mean, .names = "mean_{.col}"))

# Every numeric column at once
data %>%
    group_by(lgID) %>%
    summarise(across(where(is.numeric), mean, na.rm = TRUE))

# Several functions applied to several columns
data %>%
    group_by(teamID) %>%
    summarise(across(c(R, HR), list(avg = mean, total = sum)))

ปัจจัยสามประการที่ควบคุมพฤติกรรม:

  • .คอลัมน์: คอลัมน์ที่จะดำเนินการ เขียนด้วยตัวช่วยเดียวกันกับ select() รวมถึง where(is.numeric)
  • .fns: ฟังก์ชันหนึ่งฟังก์ชัน หรือรายการฟังก์ชันที่มีชื่อ เพื่อนำไปใช้กับแต่ละคอลัมน์
  • ชื่อ: รูปแบบการตั้งชื่อสำหรับผลลัพธ์ โดยที่ {.col} คือคอลัมน์ และ {.fn} คือชื่อฟังก์ชัน

ฟังก์ชัน `across()` ได้เข้ามาแทนที่ฟังก์ชันช่วย `summarise_all(), summarise_at()` และ `summarise_if()` เดิมใน dplyr เวอร์ชัน 1.0.0 ฟังก์ชันเหล่านั้นยังคงทำงานได้ แต่ถูกแทนที่แล้ว ดังนั้นโค้ดใหม่ควรใช้ฟังก์ชัน `across()` แทน

ข้อผิดพลาดทั่วไปของฟังก์ชัน summarise() และวิธีแก้ไข

สี่ปัญหาหลักที่เป็นสาเหตุให้การรวมข้อมูลล้มเหลวส่วนใหญ่มีดังนี้

  • ผลลัพธ์คือ NA ฟังก์ชัน mean() และ sum() จะคืนค่า NA หากมีค่าใดค่าหนึ่งหายไป ให้เพิ่ม na.rm = TRUE ดังเช่นตัวอย่าง mean_SH ด้านบน
  • ข้อความ “ฟังก์ชัน summarise() ได้จัดกลุ่มผลลัพธ์แล้ว” กลุ่มping การจัดกลุ่มผลลัพธ์โดยใช้ตัวแปรสองตัวตามตัวแปรตัวแรก ต้องใช้ `.groups = “drop”` เพื่อลบการจัดกลุ่มpingหรือเรียก ungroup() ในภายหลัง
  • การคำนวณในภายหลังให้ค่าระดับที่ไม่ถูกต้อง ดาต้าเฟรมจะยังคงอยู่ในกลุ่มเดิมจนกว่าคุณจะยกเลิกการจัดกลุ่ม ดังนั้นจึงต้องเรียกใช้ summarise() ครั้งที่สองสำหรับแต่ละกลุ่ม ซึ่งเป็นสิ่งที่ตัวอย่าง ungroup() แสดงให้เห็นอย่างชัดเจน
  • ผลลัพธ์มีจำนวนแถวมากกว่าที่คาดไว้ ฟังก์ชัน summarise() จะส่งคืนหนึ่งแถวต่อกลุ่ม ดังนั้นกลุ่มที่ไม่ได้ตั้งใจจึงอาจแสดงผลออกมาping ตัวแปรจะคูณผลลัพธ์ ตรวจสอบบรรทัด “Groups:” ที่พิมพ์อยู่เหนือตารางข้อมูลใดๆ
# Drop the grouping as part of the call
data %>%
    group_by(yearID, teamID) %>%
    summarise(mean_games = mean(G), .groups = "drop")

summarise() ใน R: คู่มืออ้างอิงฟังก์ชัน

หากต้องการแสดงผลสรุปแยกตามกลุ่ม ให้แยกข้อมูลก่อน:

# group by X1, X2, X3
group_by(df, X1, X2, X3)

และกำจัดดินping เมื่อการคำนวณเปลี่ยนระดับ:

ungroup(df)

ตารางด้านล่างแสดงรายการฟังก์ชันทั้งหมดที่ใช้ร่วมกับ summarise() ในบทช่วยสอนนี้:

วิธี ฟังก์ชัน Code
หมายความ หมายความ
summarise(df, mean_x1 = mean(x1))
มัธยฐาน มัธยฐาน
summarise(df, median_x1 = median(x1))
รวม รวม
summarise(df, sum_x1 = sum(x1))
ส่วนเบี่ยงเบนมาตรฐาน sd
summarise(df, sd_x1 = sd(x1))
ควอไทล์ ไอคิวอาร์
summarise(df, interquartile_x1 = IQR(x1))
ขั้นต่ำ นาที
summarise(df, minimum_x1 = min(x1))
สูงสุด แม็กซ์
summarise(df, maximum_x1 = max(x1))
ปริมาณ ปริมาณ
summarise(df, quantile_x1 = quantile(x1, probs = 0.75))
การสังเกตครั้งแรก เป็นครั้งแรก
summarise(df, first_x1 = first(x1))
การสังเกตครั้งสุดท้าย ล่าสุด
summarise(df, last_x1 = last(x1))
การสังเกตครั้งที่ n ที่ n
summarise(df, nth_x1 = nth(x1, 2))
จำนวนครั้งที่เกิดขึ้น n
summarise(df, n_x1 = n())
จำนวนเหตุการณ์ที่แตกต่างกัน n_แตกต่าง
summarise(df, n_distinct_x1 = n_distinct(x1))

คำถามที่พบบ่อย

summarise() จะยุบแต่ละกลุ่มให้เหลือเพียงแถวเดียวของสถิติ mutate() จะคงทุกแถวไว้และเพิ่มคอลัมน์ใหม่ ใช้ mutate() เมื่อต้องการให้สถิติของกลุ่มอยู่เคียงข้างกับข้อมูลเดิม

กลุ่มping การใช้ตัวแปรสองตัวขึ้นไปจะทำให้ผลลัพธ์ถูกจัดกลุ่มตามตัวแปรทั้งหมด ยกเว้นตัวแปรสุดท้าย dplyr จะแจ้งเตือนคุณเนื่องจากคำสั่งถัดไปจะทำงานโดยไม่แจ้งให้ทราบล่วงหน้าสำหรับแต่ละกลุ่ม หากต้องการหลีกเลี่ยงปัญหานี้ ให้ใส่ `.groups = “drop”`

n() นับทุกแถวในกลุ่มปัจจุบัน รวมถึงแถวที่ซ้ำกันด้วย n_distinct() นับค่าที่ไม่ซ้ำกันในคอลัมน์ การนับจำนวนผู้เล่นต่อทีมต้องใช้ n_distinct() เนื่องจากผู้เล่นหนึ่งคนอาจปรากฏในหลายฤดูกาล

การรวมข้อมูลระดับกลุ่ม เช่น ค่าเฉลี่ยของลูกค้า จำนวน และค่าความใหม่ เป็นตัวบ่งชี้ที่มีประสิทธิภาพมากที่สุดในแบบจำลอง AI แบบตาราง การใช้ group_by() ร่วมกับ summarise() เป็นวิธีมาตรฐานในการสร้างข้อมูลเหล่านี้อย่างแม่นยำและทำซ้ำได้

ใช่แล้ว ผู้ช่วย AI สามารถเขียนฟังก์ชัน aggregate() และ tapply() ใหม่ให้เป็นไปป์ไลน์ group_by() และ summarise() ได้ ลองเปรียบเทียบจำนวนแถวในทั้งสองเวอร์ชันดู เพราะ R พื้นฐานและ dplyr จัดการกลุ่มที่ขาดหายไปแตกต่างกัน

สรุปโพสต์นี้ด้วย: