R Select(), Filter(), Sắp xếp(), Đường dẫn có ví dụ

⚡ Tóm tắt thông minh

Select, Filter và Arrange trong R là ba lệnh của thư viện dplyr giúp thu gọn một khung dữ liệu thành các cột, hàng và thứ tự cần thiết. Hướng dẫn này sẽ kết hợp chúng với toán tử pipe trên một tập dữ liệu thời gian di chuyển gồm 205 hàng.

  • 📋 Lựa chọn cột: select(df, A, B) giữ nguyên các cột có tên, select(df, A:C) giữ nguyên một phạm vi, và select(df, -C) loại bỏ một cột.
  • 🔎 Lọc theo hàng: filter(df, condition) giữ lại các hàng khớp và điều kiện được kết hợp với dấu và (&) cho phép toán AND hoặc dấu gạch dọc cho phép toán OR.
  • 🔣 Sắp xếp: Hàm arrange() sắp xếp các hàng theo thứ tự tăng dần theo mặc định, và hàm desc() đảo ngược thứ tự của bất kỳ cột nào.
  • 🔗 Pipe Operator: Toán tử %>% truyền trực tiếp từng kết quả vào động từ tiếp theo, do đó không có đối tượng trung gian nào làm rối môi trường.
  • 🧹 Các hàm hỗ trợ: starts_with(), contains() và where() chọn các cột theo mẫu hoặc kiểu thay vì theo tên.
  • 📐 Thứ tự động từ rất quan trọng: Lọc dữ liệu sớm để thu hẹp phạm vi, sau đó chọn lọc, rồi sắp xếp, giúp giảm chi phí cho mọi bước sau.

R Chọn Lọc Sắp xếp Đường ống

dplyr trong R là gì?

dplyr là gói thao tác dữ liệu của tidyverse. Nó thay thế cú pháp ngoặc vuông của base. R Với một tập hợp nhỏ các động từ, mỗi động từ được đặt tên theo hành động mà nó thực hiện và mỗi động từ đều nhận khung dữ liệu làm đối số đầu tiên. Hình dạng nhất quán đó cho phép các động từ được xâu chuỗi với nhau.

Động từ Hành động trên Những gì nó
lựa chọn() Cột Giữ lại hoặc loại bỏ các biến
bộ lọc () Hàng Giữ lại các hàng phù hợp với điều kiện
sắp xếp() Hàng Sắp xếp lại các hàng theo một hoặc nhiều cột.
đột biến () Cột Tạo hoặc sửa đổi một biến
tóm tắt() Toàn bộ bàn Gộp nhiều hàng thành một số liệu thống kê duy nhất
nhóm theo() Toàn bộ bàn Chia dữ liệu để các động từ sau được xử lý theo từng nhóm.

Bài hướng dẫn này bao gồm ba động từ đầu tiên cộng với động từ dạng pipe. hướng dẫn về hàm tổng hợp Bài viết này trình bày chi tiết về các hàm group_by() và summarise().

Bộ dữ liệu được sử dụng trong hướng dẫn này

Thư viện dplyr chứa các động từ hữu ích để điều hướng bên trong tập dữ liệu. Thông qua hướng dẫn này, bạn sẽ sử dụng tập dữ liệu Thời gian di chuyển. Tập dữ liệu này ghi lại các chuyến đi mà người lái xe thực hiện giữa nhà và nơi làm việc. Có mười bốn biến trong tập dữ liệu, bao gồm:

  • DayOfWeek: Xác định ngày trong tuần tài xế sử dụng xe của mình
  • Khoảng cách: Tổng quãng đường của hành trình
  • MaxSpeed: Tốc độ tối đa của hành trình
  • TotalTime: Độ dài tính bằng phút của hành trình

Bộ dữ liệu bao gồm 205 quan sát, và các chuyến đi diễn ra từ... Monday Đến ngày thứ sáu.

Trước hết, bạn cần phải:

  • tải tập dữ liệu
  • kiểm tra cấu trúc dữ liệu.

Một hàm tiện dụng của dplyr là glimpse(). Nó đóng vai trò tương tự như hàm str() cơ bản trong R nhưng in ra một hàng cho mỗi biến với kiểu dữ liệu và một vài giá trị đầu tiên, giúp việc quét trên một tập dữ liệu lớn dễ dàng hơn nhiều.

library(dplyr) 
PATH <- "https://raw.githubusercontent.com/guru99-edu/R-Programming/master/travel_times.csv"
df <- read.csv(PATH)
glimpse(df)

Đầu ra:

## 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...	

Biến Comments rõ ràng cần được xem xét kỹ hơn: tất cả các quan sát đầu tiên đều trống.

sum(df$Comments =="")

Code Giải thích

  • sum(df$Comments == “”): Đếm số lượng quan sát bằng chuỗi rỗng trong cột Comments của df

Đầu ra:

## [1] 181

Sau khi dữ liệu được tải, hãy bắt đầu với động từ dùng để cắt bớt các cột.

lựa chọn()

Chúng ta sẽ bắt đầu với động từ select(). Chúng tôi không nhất thiết cần tất cả các biến và cách tốt nhất là chỉ chọn những biến bạn thấy phù hợp.

Chúng tôi có 181 quan sát bị thiếu, gần 90% tập dữ liệu. Nếu bạn quyết định loại trừ chúng, bạn sẽ không thể tiếp tục phân tích.

Khả năng khác là bỏ biến Comment bằng động từ select().

Chúng ta có thể chọn các biến theo nhiều cách khác nhau với select(). Lưu ý rằng, đối số đầu tiên là tập dữ liệu.

- `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.	

Bạn có thể sử dụng cách thứ ba để loại trừ biến Comments.

step_1_df <- select(df, -Comments)
dim(df)

Đầu ra:

## [1] 205  14
dim(step_1_df)

Đầu ra:

## [1] 205  13

Tập dữ liệu gốc có 14 tính năng trong khi step_1_df có 13 tính năng.

Hàm trợ giúp select() trong R

Việc đặt tên cho từng cột trở nên không thực tế khi tập dữ liệu có hàng chục biến. Thư viện dplyr cung cấp các hàm hỗ trợ chọn cột theo mẫu hoặc theo kiểu dữ liệu.

Người giúp đỡ Chọn các cột mà Ví dụ
starts_with() Bắt đầu với một chuỗi select(df, starts_with(“Avg”))
ends_with() Kết thúc bằng một chuỗi select(df, ends_with(“Time”))
chứa đựng() Chứa một chuỗi ký tự ở bất kỳ đâu select(df, contains(“Speed”))
diêm() So khớp biểu thức chính quy select(df, matches(“^Max|^Avg”))
Ở đâu() Đáp ứng bài kiểm tra kiểu select(df, where(is.numeric))
mọi thứ() Chưa được đặt tên. select(df, TotalTime, everything())
# 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())

Hai động từ nữa kết hợp tự nhiên với select(). Sử dụng rename(new_name = old_name) để đổi tên cột mà không cần drop.ping các cột khác, và hàm relocate() để di chuyển các cột mà không cần liệt kê tất cả.

bộ lọc ()

Hàm filter() giữ lại các quan sát thỏa mãn điều kiện. Hàm filter() hoạt động chính xác như select(), bạn truyền khung dữ liệu trước, sau đó là điều kiện được phân tách bằng dấu phẩy:

filter(df, condition)
arguments:
- df: dataset used to filter the data
- condition:  Condition used to filter the data	

Một tiêu chí

Trước hết, bạn có thể đếm số lượng quan sát trong mỗi cấp độ của một biến nhân tố.

table(step_1_df$GoingTo)

Code Giải thích

  • table(): Đếm số lượng quan sát trên mỗi cấp độ. Hàm này nhận một biến kiểu factor hoặc character.
  • bảng (step_1_df$GoingTo): Đếm số chuyến đi đến từng điểm đến

Đầu ra:

## 
##  GSK Home 
##  105  100	

Bảng hàm() cho biết 105 chuyến sẽ đến GSK và 100 chuyến sẽ về Nhà.

Chúng ta có thể lọc dữ liệu để trả về một tập dữ liệu có 105 quan sát và một tập dữ liệu khác có 100 quan sát.

# Select observations where GoingTo == Home
select_home <- filter(df, GoingTo == "Home")
dim(select_home)

Đầu ra:

## [1] 100  14
# Select observations where GoingTo == GSK (work)
select_work <- filter(df, GoingTo == "GSK")
dim(select_work)

Đầu ra:

## [1] 105  14

Nhiều tiêu chí

Chúng ta có thể lọc một tập dữ liệu bằng nhiều tiêu chí. Ví dụ, bạn có thể...tracCác quan sát này tập trung vào trường hợp điểm đến là Nhà và chuyến đi diễn ra vào thứ Tư.

select_home_wed <- filter(df, GoingTo == "Home" & DayOfWeek == "Wednesday")
dim(select_home_wed)

Đầu ra:

## [1] 23 14

23 quan sát phù hợp với tiêu chí này.

Các điều kiện thường gặp của hàm filter() và Operators trong R

Hàm filter() giữ lại mọi hàng mà điều kiện được đánh giá là TRUE. Các hàng có giá trị NA sẽ bị loại bỏ, đây là hành vi khiến hầu hết người mới bắt đầu ngạc nhiên.

Operator Ý nghĩa Ví dụ
== Tương đương với filter(df, GoingTo == “Home”)
!= Không bằng lọc(df, DayOfWeek != “Monday")
& VÀ, cả hai đều phải đáp ứng filter(df, Distance > 50 & MaxSpeed ​​> 130)
| HOẶC, một trong hai trường hợp đều có thể xảy ra. lọc(df, DayOfWeek == “Monday” | Ngày trong tuần == “Thứ Sáu”)
%TRONG% Khớp với bất kỳ giá trị nào trong một vectơ filter(df, DayOfWeek %in% c(“Monday", "Thứ sáu"))
giữa() Nằm trong một phạm vi số lọc(df, giữa(Khoảng cách, 48, 52))
là.na() Giá trị bị thiếu filter(df, is.na(FuelEconomy))

Ba thói quen này giúp ngăn ngừa hầu hết các lỗi của hàm filter().

  • Hãy sử dụng %in% thay vì toán tử OR nối tiếp. filter(df, DayOfWeek %in% c(“Monday“Friday”)) ngắn gọn hơn và khó gõ sai hơn nhiều so với hai phép so sánh == được nối bằng dấu gạch dọc.
  • Không bao giờ kiểm tra giá trị thiếu bằng toán tử ==. Biểu thức x == NA trả về NA chứ không phải TRUE, vì vậy hàng đó bị xóa một cách im lặng. Thay vào đó, hãy sử dụng is.na(x).
  • Dấu phẩy có nghĩa là VÀ. filter(df, a, b) hoàn toàn giống với filter(df, a & b), đó là lý do tại sao ví dụ trước đó trong hướng dẫn này hoạt động theo cả hai cách.

Ống Operator trong dplyr

Việc tạo một tập dữ liệu đòi hỏi rất nhiều thao tác, chẳng hạn như:

  • nhập khẩu
  • sáp nhập
  • lựa chọn
  • lọc
  • và vv

Thư viện dplyr đi kèm với một toán tử thực tế, %>%, được gọi là đường ốngNó giúp việc thao tác dữ liệu trở nên sạch sẽ hơn, nhanh hơn và ít xảy ra lỗi hơn.

Toán tử này là mã thực hiện các bước mà không lưu các bước trung gian vào ổ cứng. Nếu bạn quay lại ví dụ trên của chúng tôi, bạn có thể chọn các biến quan tâm và lọc chúng. Chúng tôi có ba bước:

  • Bước 1: Nhập dữ liệu: Nhập dữ liệu gps
  • Bước 2: Chọn dữ liệu: Chọn GoingTo và DayOfWeek
  • Bước 3: Lọc dữ liệu: Chỉ trả về Nhà và Thứ Tư

Chúng ta có thể sử dụng cách khó để làm điều đó:

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

Đầu ra:

##   GoingTo DayOfWeek
## 1    Home Wednesday
## 2    Home Wednesday
## 3    Home Wednesday
## 4    Home Wednesday
## 5    Home Wednesday
## 6    Home Wednesday	

Đó không phải là cách thuận tiện để xâu chuỗi nhiều thao tác. Mọi kết quả trung gian đều nằm trong môi trường và tên gọi của chúng nhanh chóng trở nên vô nghĩa.

Hãy sử dụng toán tử đường ống %>% thay thế. Bạn chỉ cần đặt tên cho khung dữ liệu một lần ở đầu và mọi bước tiếp theo sẽ được thực hiện từ tên đó.

Cú pháp cơ bản của đường ống

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.

Bạn có thể tạo đường ống đầu tiên của mình bằng cách thực hiện theo các bước được liệt kê ở trên.

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

Đầu ra:

## [1] TRUE

Hai đối tượng này giống hệt nhau, vì vậy đường ống tạo ra kết quả chính xác như nhau trong một câu lệnh duy nhất dễ đọc.

sắp xếp()

Trong tạp chí hướng dẫn trước, bạn học cách sắp xếp các giá trị bằng hàm sắp xếp(). Thư viện dplyr có chức năng sắp xếp. Nó hoạt động như một sự quyến rũ với đường ống. Động từ sắp xếp() có thể sắp xếp lại một hoặc nhiều hàng, tăng dần (mặc định) hoặc giảm dần.

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

Chúng ta có thể sắp xếp khoảng cách theo điểm đến.

# Sort by destination and distance
step_2_df <- step_1_df %>%
    arrange(GoingTo, Distance)
head(step_2_df)

Đầu ra:

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

Các động từ dplyr trong R: Tham khảo nhanh

Bảng dưới đây liệt kê tất cả các động từ được sử dụng trong hướng dẫn này, cùng với cú pháp và giá trị trả về của mỗi lệnh gọi:

Động từ Mục tiêu Code Giải thích
nhìn thoáng qua kiểm tra cấu trúc của một df
glimpse(df)
Chức năng tương tự như str(), nhưng dễ đọc hơn.
lựa chọn() Chọn/loại trừ các biến
select(df, A, B ,C)
Chọn các biến A, B và C
select(df, A:C)
Chọn tất cả các biến từ A đến C
select(df, -C)
Loại trừ C
bộ lọc () Giữ các hàng khớp với một hoặc nhiều điều kiện.
filter(df, condition1)
Một điều kiện
filter(df, condition1 & condition2)
Hai điều kiện kết hợp với toán tử AND
sắp xếp() Sắp xếp tập dữ liệu với một hoặc nhiều biến
arrange(A)
Sắp xếp tăng dần của biến A
arrange(A, B)
Sắp xếp tăng dần của biến A và B
arrange(desc(A), B)
Sắp xếp giảm dần của biến A và sắp xếp tăng dần của biến B
%>% Tạo một đường dẫn giữa mỗi bước
step 1 %>% step 2 %>% step 3

Câu Hỏi Thường Gặp

Toán tử pipe %>% của magrittr được tích hợp sẵn trong dplyr và hỗ trợ cú pháp giữ chỗ với dấu chấm. Toán tử pipe |> gốc xuất hiện trong R 4.1 và không cần gói nào. Cả hai đều truyền kết quả bên trái vào đối số đầu tiên bên phải.

Không. Mỗi lệnh của dplyr đều trả về một data frame mới và giữ nguyên data frame ban đầu. Bạn phải gán kết quả cho một đối tượng hoặc truyền nó đi tiếp để thay đổi được lưu lại.

So sánh với NA sẽ trả về NA thay vì TRUE, và hàm filter() chỉ giữ lại các hàng có giá trị TRUE. Sử dụng is.na() để chọn các giá trị thiếu một cách có chủ đích, hoặc sử dụng drop_na() từ tidyr để loại bỏ chúng.

Kỹ thuật trích chọn đặc trưng cho các mô hình AI chủ yếu bao gồm lọc hàng, chọn cột và sắp xếp. Thư viện dplyr thể hiện các bước này dưới dạng các quy trình dễ đọc mà người đánh giá có thể kiểm tra, điều này rất quan trọng khi tập dữ liệu huấn luyện cần phải có tính tái tạo.

Đúng vậy. Trợ lý AI có thể dịch việc chọn tập con trong ngoặc thành các lệnh select() và filter() và giải thích cú pháp pipe. Luôn chạy cả hai phiên bản và so sánh kích thước, vì R cơ bản và dplyr xử lý các giá trị thiếu khác nhau.

Tóm tắt bài viết này với: