R เลือก(), กรอง(), จัดเรียง(), ไปป์ไลน์พร้อมตัวอย่าง
⚡ สรุปอย่างชาญฉลาด
Select, Filter และ Arrange ใน R เป็นคำสั่งสามคำสั่งของ dplyr ที่ใช้ลดขนาด Data Frame ให้เหลือเฉพาะคอลัมน์ แถว และลำดับที่คุณต้องการ บทความนี้จะเชื่อมโยงคำสั่งเหล่านี้เข้าด้วยกันโดยใช้ตัวดำเนินการ pipe กับชุดข้อมูลเวลาเดินทางที่มี 205 แถว
dplyr ใน R คืออะไร?
ดีพลีร์ เป็นแพ็กเกจจัดการข้อมูลของ tidyverse โดยจะแทนที่สัญลักษณ์วงเล็บเหลี่ยมของเวอร์ชันพื้นฐาน R โดยใช้ชุดคำกริยาขนาดเล็ก แต่ละคำตั้งชื่อตามการกระทำที่มันทำ และแต่ละคำรับข้อมูลเฟรมเป็นอาร์กิวเมนต์แรก รูปแบบที่สม่ำเสมอนี้เองที่ทำให้สามารถเชื่อมโยงคำกริยาเข้าด้วยกันได้
| คำกริยา | การกระทำต่อ | สิ่งที่มันไม่ |
|---|---|---|
| เลือก() | คอลัมน์ | คงค่าหรือลบตัวแปร |
| กรอง() | แถว | เก็บแถวที่ตรงกับเงื่อนไข |
| จัด() | แถว | จัดเรียงแถวใหม่ตามคอลัมน์หนึ่งคอลัมน์ขึ้นไป |
| กลายพันธุ์() | คอลัมน์ | สร้างหรือแก้ไขตัวแปร |
| สรุป() | โต๊ะทั้งโต๊ะ | ยุบรวมหลายแถวให้เหลือเพียงสถิติเดียว |
| group_by() | โต๊ะทั้งโต๊ะ | แบ่งข้อมูลเพื่อให้คำกริยาถัดไปทำงานแยกตามกลุ่ม |
บทเรียนนี้ครอบคลุมคำกริยาสามคำแรก รวมทั้งคำกริยาที่มีเครื่องหมายไปป์ด้วย บทช่วยสอนฟังก์ชันรวม อธิบายรายละเอียดเกี่ยวกับ group_by() และ summarise() อย่างลึกซึ้ง
ชุดข้อมูลที่ใช้ในบทช่วยสอนนี้
ไลบรารีที่ชื่อว่า dplyr มีคำสั่งที่มีประโยชน์มากมายสำหรับการนำทางภายในชุดข้อมูล ในบทเรียนนี้ คุณจะใช้ชุดข้อมูลเวลาเดินทาง ชุดข้อมูลนี้บันทึกการเดินทางของคนขับรถระหว่างบ้านและที่ทำงาน มีตัวแปรทั้งหมดสิบสี่ตัวในชุดข้อมูล ได้แก่:
- DayOfWeek: ระบุวันในสัปดาห์ที่คนขับใช้รถของเขา
- ระยะทาง: ระยะทางรวมของการเดินทาง
- MaxSpeed: ความเร็วสูงสุดของการเดินทาง
- TotalTime: ความยาวเป็นนาทีของการเดินทาง
ชุดข้อมูลประกอบด้วยข้อมูลสังเกตการณ์ 205 รายการ และการเดินทางเกิดขึ้นระหว่าง Monday ถึงวันศุกร์
ก่อนอื่น คุณต้อง:
- โหลดชุดข้อมูล
- ตรวจสอบโครงสร้างของข้อมูล
ฟังก์ชันที่มีประโยชน์อย่างหนึ่งของ dplyr คือ glimpse() มันทำหน้าที่เหมือนกับ str() ในภาษา R แต่จะพิมพ์ข้อมูลทีละแถวต่อตัวแปร โดยแสดงชนิดข้อมูลและค่าเริ่มต้นไม่กี่ค่า ซึ่งง่ายต่อการตรวจสอบในชุดข้อมูลขนาดใหญ่มากกว่า
library(dplyr) PATH <- "https://raw.githubusercontent.com/guru99-edu/R-Programming/master/travel_times.csv" df <- read.csv(PATH) glimpse(df)
Output:
## Observations: 205 ## Variables: 14 ## $ X <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ... ## $ Date <fctr> 1/6/2012, 1/6/2012, 1/4/2012, 1/4/2012, 1/3/20... ## $ StartTime <fctr> 16:37, 08:20, 16:17, 07:53, 18:57, 07:57, 17:3... ## $ DayOfWeek <fctr> Friday, Friday, Wednesday, Wednesday, Tuesday,... ## $ GoingTo <fctr> Home, GSK, Home, GSK, Home, GSK, Home, GSK, GS... ## $ Distance <dbl> 51.29, 51.63, 51.27, 49.17, 51.15, 51.80, 51.37... ## $ MaxSpeed <dbl> 127.4, 130.3, 127.4, 132.3, 136.2, 135.8, 123.2... ## $ AvgSpeed <dbl> 78.3, 81.8, 82.0, 74.2, 83.4, 84.5, 82.9, 77.5,... ## $ AvgMovingSpeed <dbl> 84.8, 88.9, 85.8, 82.9, 88.1, 88.8, 87.3, 85.9,... ## $ FuelEconomy <fctr> , , , , , , -, -, 8.89, 8.89, 8.89, 8.89, 8.89... ## $ TotalTime <dbl> 39.3, 37.9, 37.5, 39.8, 36.8, 36.8, 37.2, 37.9,... ## $ MovingTime <dbl> 36.3, 34.9, 35.9, 35.6, 34.8, 35.0, 35.3, 34.3,... ## $ Take407All <fctr> No, No, No, No, No, No, No, No, No, No, No, No... ## $ Comments <fctr> , , , , , , , , , , , , , , , Put snow tires o...
ตัวแปร Comments จำเป็นต้องได้รับการตรวจสอบอย่างละเอียดถี่ถ้วน เนื่องจากข้อมูลชุดแรกว่างเปล่าทั้งหมด
sum(df$Comments =="")
Code คำอธิบาย
- sum(df$Comments == “”): นับจำนวนข้อมูลที่เท่ากับสตริงว่างในคอลัมน์ Comments ของ df
Output:
## [1] 181
เมื่อโหลดข้อมูลเสร็จแล้ว ให้เริ่มต้นด้วยคำสั่งที่ใช้ตัดแต่งคอลัมน์
เลือก()
เราจะเริ่มต้นด้วยกริยา select() เราไม่จำเป็นต้องใช้ตัวแปรทั้งหมด และแนวทางปฏิบัติที่ดีคือเลือกเฉพาะตัวแปรที่คุณคิดว่าเกี่ยวข้องเท่านั้น
เรามีข้อสังเกตที่ขาดหายไป 181 รายการ เกือบ 90 เปอร์เซ็นต์ของชุดข้อมูล หากคุณตัดสินใจที่จะยกเว้น คุณจะไม่สามารถดำเนินการวิเคราะห์ต่อไปได้
ความเป็นไปได้อีกอย่างคือปล่อยตัวแปร Comment ด้วยกริยา select()
เราสามารถเลือกตัวแปรได้หลายวิธีด้วย select() โปรดทราบว่าอาร์กิวเมนต์แรกคือชุดข้อมูล
- `select(df, A, B ,C)`: Select the variables A, B and C from df dataset. - `select(df, A:C)`: Select all variables from A to C from df dataset. - `select(df, -C)`: Exclude C from the dataset from df dataset.
คุณสามารถใช้วิธีที่สามเพื่อยกเว้นตัวแปร Comments
step_1_df <- select(df, -Comments) dim(df)
Output:
## [1] 205 14
dim(step_1_df)
Output:
## [1] 205 13
ชุดข้อมูลดั้งเดิมมี 14 คุณสมบัติในขณะที่ step_1_df มี 13 คุณสมบัติ
ฟังก์ชันตัวช่วย select() ใน R
การตั้งชื่อคอลัมน์ทุกคอลัมน์กลายเป็นเรื่องยากเมื่อชุดข้อมูลมีตัวแปรหลายสิบตัว dplyr มีตัวช่วยที่เลือกคอลัมน์ตามรูปแบบหรือตามประเภทแทน
| ผู้ช่วยเหลือ | เลือกคอลัมน์ที่ | ตัวอย่าง |
|---|---|---|
| เริ่มต้นด้วย() | เริ่มต้นด้วยเส้นด้าย | เลือก (df, ขึ้นต้นด้วย “ค่าเฉลี่ย”)) |
| จบด้วย() | จบด้วยเชือก | เลือก (df, ends_with("เวลา")) |
| ประกอบด้วย() | มีสตริงอยู่ทุกที่ | เลือก (df, มีคำว่า “ความเร็ว” อยู่) |
| แมตช์() | ตรงกับนิพจน์ปกติ | เลือก (df, matches(“^Max|^Avg”)) |
| ที่ไหน() | ผ่านการทดสอบประเภท | เลือก (df, where(is.numeric)) |
| ทุกอย่าง() | ยังไม่มีการตั้งชื่อ | เลือก (df, TotalTime, ทุกอย่าง()) |
# Keep only the timing columns df %>% select(ends_with("Time")) # Keep every numeric column df %>% select(where(is.numeric)) # Move TotalTime to the front, keep the rest in place df %>% select(TotalTime, everything())
มีคำกริยาอีกสองคำที่เข้ากันได้ดีกับ select() ใช้ rename(new_name = old_name) เพื่อเปลี่ยนชื่อคอลัมน์โดยไม่ต้องลบออกping ส่วนคอลัมน์อื่นๆ และใช้ฟังก์ชัน relocate() เพื่อย้ายคอลัมน์โดยไม่ต้องระบุทั้งหมด
กรอง()
คำสั่ง `filter()` จะเก็บเฉพาะข้อมูลที่ตรงตามเงื่อนไข การทำงานของ `filter()` เหมือนกับ `select()` ทุกประการ คือ คุณต้องส่ง data frame เข้าไปก่อน แล้วตามด้วยเงื่อนไขที่คั่นด้วยเครื่องหมายจุลภาค:
filter(df, condition)
arguments:
- df: dataset used to filter the data
- condition: Condition used to filter the data
เกณฑ์หนึ่ง
ประการแรก คุณสามารถนับจำนวนการสังเกตภายในแต่ละระดับของตัวแปรปัจจัยได้
table(step_1_df$GoingTo)
Code คำอธิบาย
- table(): นับจำนวนข้อมูลต่อระดับ โดยฟังก์ชันนี้ต้องการตัวแปรประเภท factor หรือ character
- ตาราง(step_1_df$GoingTo): นับจำนวนการเดินทางไปยังแต่ละจุดหมายปลายทาง
Output:
## ## GSK Home ## 105 100
ตารางฟังก์ชัน() ระบุว่ามีรถ 105 คันไปที่ GSK และ 100 คันไปที่ Home
เราสามารถกรองข้อมูลเพื่อส่งคืนชุดข้อมูลชุดหนึ่งที่มีการสังเกต 105 ครั้ง และอีกชุดหนึ่งที่มีการสังเกต 100 ครั้ง
# Select observations where GoingTo == Home select_home <- filter(df, GoingTo == "Home") dim(select_home)
Output:
## [1] 100 14
# Select observations where GoingTo == GSK (work) select_work <- filter(df, GoingTo == "GSK") dim(select_work)
Output:
## [1] 105 14
เกณฑ์หลายประการ
เราสามารถกรองชุดข้อมูลโดยใช้เกณฑ์มากกว่าหนึ่งข้อได้ ตัวอย่างเช่น คุณสามารถยกตัวอย่างได้ดังนี้tracจากการสังเกตการณ์ที่จุดหมายปลายทางคือบ้าน และการเดินทางเกิดขึ้นในวันพุธ
select_home_wed <- filter(df, GoingTo == "Home" & DayOfWeek == "Wednesday") dim(select_home_wed)
Output:
## [1] 23 14
ข้อสังเกต 23 รายการตรงกับเกณฑ์นี้
เงื่อนไขตัวกรองทั่วไป() และ Operaทอร์ในอาร์
ฟังก์ชัน filter() จะเก็บเฉพาะแถวที่ตรงตามเงื่อนไข TRUE เท่านั้น ส่วนแถวที่ตรงตามเงื่อนไข NA จะถูกตัดทิ้ง ซึ่งเป็นพฤติกรรมที่ทำให้ผู้เริ่มต้นส่วนใหญ่แปลกใจ
| OperaTor | ความหมาย | ตัวอย่าง |
|---|---|---|
| == | เท่ากับ | filter(df, GoingTo == “Home”) |
| != | ไม่เท่ากับ | กรอง (df, วันในสัปดาห์ != “Monday") |
| & | และทั้งสองต้องคงอยู่ | filter(df, Distance > 50 & MaxSpeed > 130) |
| | | หรือ ฝ่ายใดฝ่ายหนึ่งอาจถือครองทรัพย์สินได้ | กรอง (df, วันในสัปดาห์ == “Monday” | วันในสัปดาห์ == “วันศุกร์”) |
| %ใน% | ตรงกับค่าใดๆ ในเวกเตอร์ | filter(df, DayOfWeek %in% c(“Monday", "วันศุกร์")) |
| ระหว่าง() | อยู่ในช่วงตัวเลขที่กำหนด | กรอง (df, ระหว่าง (ระยะทาง, 48, 52)) |
| คือ.นา() | ค่าที่หายไป | กรอง (df, is.na(FuelEconomy)) |
สามพฤติกรรมหลักช่วยป้องกันข้อผิดพลาดของฟังก์ชัน filter() ส่วนใหญ่ได้
- ใช้ %in% แทนการใช้ OR แบบต่อเนื่อง filter(df, DayOfWeek %in% c(“Monday“, “วันศุกร์”)) สั้นกว่าและพิมพ์ผิดยากกว่าการเปรียบเทียบด้วยเครื่องหมาย == สองตัวที่เชื่อมด้วยเส้นแนวตั้งมาก
- ห้ามทดสอบค่าที่หายไปโดยใช้เครื่องหมาย == เด็ดขาด นิพจน์ x == NA จะส่งคืนค่า NA ไม่ใช่ TRUE ดังนั้นแถวนั้นจะถูกละทิ้งโดยไม่มีการแจ้งเตือนใดๆ ให้ใช้ is.na(x) แทน
- เครื่องหมายจุลภาคหมายถึง "และ" filter(df, a, b) นั้นเหมือนกับ filter(df, a & b) ทุกประการ ซึ่งเป็นเหตุผลว่าทำไมตัวอย่างก่อนหน้านี้ในบทเรียนนี้จึงใช้งานได้ทั้งสองแบบ
ท่อ Operator ใน dplyr
การสร้างชุดข้อมูลต้องมีการดำเนินการมากมาย เช่น:
- การนำเข้า
- การผสม
- การเลือก
- กรอง
- เป็นต้น
ไลบรารี dplyr มาพร้อมกับตัวดำเนินการใช้งานจริง %>% เรียกว่า ท่อมันทำให้การจัดการข้อมูลมีความสะอาด รวดเร็ว และลดโอกาสเกิดข้อผิดพลาด
ตัวดำเนินการนี้เป็นโค้ดที่ดำเนินการขั้นตอนต่างๆ โดยไม่บันทึกขั้นตอนกลางๆ ลงในฮาร์ดไดรฟ์ หากคุณกลับมาดูตัวอย่างด้านบน คุณสามารถเลือกตัวแปรที่สนใจและกรองตัวแปรเหล่านั้นได้ เรามีสามขั้นตอน:
- ขั้นตอนที่ 1: นำเข้าข้อมูล: นำเข้าข้อมูล GPS
- ขั้นตอนที่ 2: เลือกข้อมูล: เลือก GoingTo และ DayOfWeek
- ขั้นตอนที่ 3: กรองข้อมูล: ส่งคืนเฉพาะหน้าแรกและวันพุธ
เราสามารถใช้วิธีที่ยากในการทำมันได้:
# Step 1 step_1 <- read.csv(PATH) # Step 2 step_2 <- select(step_1, GoingTo, DayOfWeek) # Step 3 step_3 <- filter(step_2, GoingTo == "Home", DayOfWeek == "Wednesday") head(step_3)
Output:
## GoingTo DayOfWeek ## 1 Home Wednesday ## 2 Home Wednesday ## 3 Home Wednesday ## 4 Home Wednesday ## 5 Home Wednesday ## 6 Home Wednesday
นั่นไม่ใช่วิธีที่สะดวกในการเชื่อมโยงการดำเนินการหลายๆ อย่างเข้าด้วยกัน ผลลัพธ์ระหว่างกลางทุกอย่างจะยังคงอยู่ในสภาพแวดล้อม และชื่อเหล่านั้นก็จะไม่มีความหมายอะไรอีกต่อไปในไม่ช้า
ให้ใช้ตัวดำเนินการไปป์ %>% แทน คุณตั้งชื่อเฟรมข้อมูลเพียงครั้งเดียวในตอนเริ่มต้น และทุกขั้นตอนจะดำเนินไปตามนั้น
ไวยากรณ์พื้นฐานของไปป์ไลน์
New_df <- df %>% step 1 %>% step 2 %>% ... arguments - New_df: Name of the new data frame - df: Data frame used to compute the step - step: Instruction for each step - Note: the last instruction does not need a trailing `%>%`, because nothing follows it - Note: assigning the result to a new object is optional. Without it, the output prints in the console.
คุณสามารถสร้างท่อแรกของคุณได้โดยทำตามขั้นตอนที่ระบุไว้ข้างต้น
# Create the data frame filter_home_wed.It will be the object return at the end of the pipeline filter_home_wed <- #Step 1 read.csv(PATH) %>% #Step 2 select(GoingTo, DayOfWeek) %>% #Step 3 filter(GoingTo == "Home",DayOfWeek == "Wednesday") identical(step_3, filter_home_wed)
Output:
## [1] TRUE
วัตถุทั้งสองเหมือนกันทุกประการ ดังนั้นการใช้คำสั่ง pipe จึงให้ผลลัพธ์ที่เหมือนกันทุกประการในประโยคเดียวที่อ่านง่าย
จัด()
ตัว Vortex Indicator ได้ถูกนำเสนอลงในนิตยสาร กวดวิชาก่อนหน้านี้คุณจะได้เรียนรู้วิธีจัดเรียงค่าด้วยฟังก์ชัน sort() ไลบรารี dplyr มีฟังก์ชันการเรียงลำดับ มันใช้งานได้อย่างมีเสน่ห์กับไปป์ไลน์ กริยา Arrange() สามารถเรียงลำดับแถวใหม่ได้ตั้งแต่หนึ่งแถวขึ้นไป (ค่าเริ่มต้น) หรือจากมากไปน้อย
- `arrange(A)`: Ascending sort of variable A - `arrange(A, B)`: Ascending sort of variable A and B - `arrange(desc(A), B)`: Descending sort of variable A and ascending sort of B
เราสามารถจัดเรียงระยะทางตามจุดหมายปลายทางได้
# Sort by destination and distance step_2_df <- step_1_df %>% arrange(GoingTo, Distance) head(step_2_df)
Output:
## X Date StartTime DayOfWeek GoingTo Distance MaxSpeed AvgSpeed ## 1 193 7/25/2011 08:06 Monday GSK 48.32 121.2 63.4 ## 2 196 7/21/2011 07:59 Thursday GSK 48.35 129.3 81.5 ## 3 198 7/20/2011 08:24 Wednesday GSK 48.50 125.8 75.7 ## 4 189 7/27/2011 08:15 Wednesday GSK 48.82 124.5 70.4 ## 5 95 10/11/2011 08:25 Tuesday GSK 48.94 130.8 85.7 ## 6 171 8/10/2011 08:13 Wednesday GSK 48.98 124.8 72.8 ## AvgMovingSpeed FuelEconomy TotalTime MovingTime Take407All ## 1 78.4 8.45 45.7 37.0 No ## 2 89.0 8.28 35.6 32.6 Yes ## 3 87.3 7.89 38.5 33.3 Yes ## 4 77.8 8.45 41.6 37.6 No ## 5 93.2 7.81 34.3 31.5 Yes ## 6 78.8 8.54 40.4 37.3 No
คำกริยาใน R ที่ใช้ dplyr: คู่มืออ้างอิงฉบับย่อ
ตารางด้านล่างแสดงรายการคำกริยาทุกคำที่ใช้ในบทช่วยสอนนี้ พร้อมด้วยไวยากรณ์และค่าที่แต่ละคำสั่งส่งคืน:
| คำกริยา | วัตถุประสงค์ | Code | คำอธิบาย |
|---|---|---|---|
| เหลือบ | ตรวจสอบโครงสร้างของ df |
glimpse(df)
|
มีจุดประสงค์เดียวกันกับ str() แต่ดูง่ายกว่า |
| เลือก() | เลือก/ไม่รวมตัวแปร |
select(df, A, B ,C)
|
เลือกตัวแปร A, B และ C |
select(df, A:C)
|
เลือกตัวแปรทั้งหมดจาก A ถึง C | ||
select(df, -C)
|
ไม่รวม C | ||
| กรอง() | รักษาแถวให้ตรงตามเงื่อนไขอย่างน้อยหนึ่งข้อ |
filter(df, condition1)
|
เงื่อนไขหนึ่ง |
filter(df, condition1 & condition2)
|
สองเงื่อนไขที่รวมกันด้วย AND | ||
| จัด() | จัดเรียงชุดข้อมูลด้วยตัวแปรหนึ่งหรือหลายตัวแปร |
arrange(A)
|
การเรียงลำดับของตัวแปร A จากน้อยไปหามาก |
arrange(A, B)
|
การเรียงลำดับของตัวแปร A และ B จากน้อยไปหามาก | ||
arrange(desc(A), B)
|
การเรียงลำดับของตัวแปร A จากมากไปน้อยและการเรียงลำดับจากน้อยไปหามากของ B | ||
| - | สร้างไปป์ไลน์ระหว่างแต่ละขั้นตอน |
step 1 %>% step 2 %>% step 3 |

