Hướng dẫn sử dụng dplyr trong R: Ghép và nối dữ liệu với ví dụ
⚡ Tóm tắt thông minh
Thư viện dplyr hợp nhất và kết hợp các khung dữ liệu trong R bằng bốn lệnh: left_join(), right_join(), inner_join() và full_join(). Gói đi kèm tidyr sau đó định hình lại kết quả đã kết hợp bằng cách sử dụng gather(), spread(), separate() và unite().

Giới thiệu về Phân tích Dữ liệu
Trước khi bất kỳ sự tham gia hoặc resha nàoping Động từ này nghe có vẻ hợp lý, giúp ta hiểu rõ hơn việc thao tác dữ liệu phù hợp ở đâu. Phân tích dữ liệu có thể được chia thành ba phần:
- Extracsản xuất: Đầu tiên, chúng ta cần thu thập dữ liệu từ nhiều nguồn và kết hợp chúng lại.
- Chuyển đổi: Bước này liên quan đến việc thao tác dữ liệu. Khi chúng tôi đã hợp nhất tất cả các nguồn dữ liệu, chúng tôi có thể bắt đầu làm sạch dữ liệu.
- Hình dung: Động thái cuối cùng là trực quan hóa dữ liệu của chúng tôi để kiểm tra sự bất thường.
Sơ đồ bên dưới cho thấy ba giai đoạn này liên kết với nhau như thế nào.

Một trong những thách thức lớn nhất mà các nhà khoa học dữ liệu phải đối mặt là thao tác dữ liệu. Dữ liệu không bao giờ có sẵn ở định dạng mong muốn. Các nhà khoa học dữ liệu cần dành ít nhất một nửa thời gian để làm sạch và thao tác dữ liệu. Đó là một trong những nhiệm vụ quan trọng nhất trong công việc. Nếu quá trình thao tác dữ liệu không hoàn chỉnh, chính xác và chặt chẽ, mô hình sẽ không hoạt động chính xác.
R dplyr
R có một gói gọi là dplyr dùng để xử lý việc chuyển đổi dữ liệu. Nó được xây dựng dựa trên một tập hợp nhỏ các lệnh cốt lõi — filter(), select(), arrange(), mutate() và summarise() — cùng với một nhóm các hàm kết hợp. Sau khi dữ liệu được định dạng, ggplot2 có thể trực quan hóa nó.
Chúng ta sẽ học cách sử dụng gói dplyr để thao tác với một đối tượng. Khung dữ liệuNếu R chưa được cài đặt, hãy làm theo hướng dẫn sau. Các bước thiết lập R và RStudiosau đó chạy install.packages(“dplyr”).
Ghép dữ liệu bằng dplyr
dplyr cung cấp một cách hay và thuận tiện để kết hợp các tập dữ liệu. Chúng ta có thể có nhiều nguồn dữ liệu đầu vào và đến một lúc nào đó, chúng ta cần kết hợp chúng lại. Kết hợp với dplyr sẽ thêm các biến ở bên phải tập dữ liệu gốc.
dplyr Tham gia
Sau đây là bốn loại phép nối quan trọng được sử dụng trong dplyr để hợp nhất hai tập dữ liệu. Cả bốn đều nhận cùng các đối số — hai bảng và khóa — và chỉ khác nhau ở việc giữ lại những hàng không khớp:
| Chức năng | Mục tiêu | Lập luận | Nhiều phím |
|---|---|---|---|
| chỗ nối bên trái() | Hợp nhất hai tập dữ liệu. Giữ tất cả các quan sát từ bảng gốc | x, y, by = “ID” | x, y, by = c(“ID”, “ID2”) |
| phải_join() | Hợp nhất hai tập dữ liệu. Giữ tất cả các quan sát từ bảng đích | x, y, by = “ID” | x, y, by = c(“ID”, “ID2”) |
| bên trong_join() | Kết hợp hai tập dữ liệu. Loại bỏ tất cả các hàng không khớp. | x, y, by = “ID” | x, y, by = c(“ID”, “ID2”) |
| full_join() | Kết hợp hai tập dữ liệu. Giữ lại tất cả các quan sát. | x, y, by = “ID” | x, y, by = c(“ID”, “ID2”) |
Bốn động từ này tương ứng với các phép nối TRÁI, PHẢI, TRONG và NGOÀI HOÀN TOÀN của SQL. R cơ bản đạt được kết quả tương tự thông qua các đối số all, all.x và all.y của hợp nhất ().
Chúng ta sẽ nghiên cứu tất cả các loại phép nối thông qua một ví dụ đơn giản.
Trước hết, chúng ta xây dựng hai tập dữ liệu. Bảng 1 chứa hai biến, ID và y, trong khi Bảng 2 thu thập ID và z. Trong mỗi trường hợp, chúng ta cần có một cặp khóa Biến đổi. Trong trường hợp của chúng tôi, ID là của chúng tôi chính biến. Hàm này sẽ tìm kiếm các giá trị giống hệt nhau trong cả hai bảng và gán các giá trị trả về vào bên phải của bảng 1. Hình dưới đây cho thấy hai bảng đặt cạnh nhau.
library(dplyr) df_primary <- tribble( ~ID, ~y, "A", 5, "B", 5, "C", 8, "D", 0, "F", 9) df_secondary <- tribble( ~ID, ~z, "A", 30, "B", 21, "C", 22, "D", 25, "E", 29)
dplyr left_join()
Cách phổ biến nhất để hợp nhất hai tập dữ liệu là sử dụng hàm left_join(). Hình ảnh bên dưới cho thấy cặp khóa khớp với các hàng A, B, C và D, trong khi E và F bị bỏ lại. Với left_join(), chúng ta giữ lại tất cả các hàng trong bảng gốc và bỏ qua các hàng không có cặp khóa trong bảng đích. Trong ví dụ của chúng ta, giá trị E không tồn tại trong bảng 1, vì vậy hàng đó bị loại bỏ. Giá trị F đến từ bảng gốc, vì vậy nó được giữ lại sau khi thực hiện left_join() và trả về NA trong cột z.
Ví dụ về dplyr left_join()
Sơ đồ bên dưới mô tả những gì xảy ra trong quá trình thực hiện left_join().
left_join(df_primary, df_secondary, by ='ID')
Đầu ra:
## # A tibble: 5 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25 ## 5 F 9 NA
Lưu ý rằng khi cả hai bảng đều có một cột cùng tên, dplyr sẽ phân biệt chúng bằng các hậu tố .x và .y như đã nêu ở trên.
dplyr right_join()
Hàm right_join() hoạt động chính xác như left_join(). Sự khác biệt duy nhất là hàng bị bỏ. Giá trị E có sẵn trong khung dữ liệu đích, tồn tại trong bảng mới và lấy giá trị NA cho cột y.
Ví dụ về dplyr right_join()
Sơ đồ bên dưới thể hiện hình ảnh phản chiếu.
right_join(df_primary, df_secondary, by = 'ID')
Đầu ra:
## # A tibble: 5 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25 ## 5 E NA 29
dplyr inner_join()
Khi các quan sát không khớp hoàn toàn vô dụng, chúng ta có thể quay lại. có thể các hàng tồn tại trong cả hai Các tập dữ liệu. Đây là lựa chọn phù hợp khi chúng ta cần một tập dữ liệu hoàn chỉnh và không muốn điền các giá trị thiếu bằng giá trị trung bình hoặc trung vị.
Hàm inner_join() sẽ giúp ích trong trường hợp này. Nó loại bỏ các hàng không khớp ở cả hai phía.
Ví dụ về dplyr Inner_join()
Sơ đồ bên dưới minh họa bốn ID còn lại sau khi kết nối.
inner_join(df_primary, df_secondary, by ='ID')
Đầu ra:
## # A tibble: 4 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25
dplyr full_join()
Cuối cùng, hàm full_join() giữ lại tất cả các quan sát và thay thế các giá trị thiếu bằng NA.
Ví dụ về dplyr full_join()
Sơ đồ bên dưới hiển thị tất cả các ID từ cả hai bảng còn lại sau phép nối.
full_join(df_primary, df_secondary, by = 'ID')
Đầu ra:
## # A tibble: 6 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25 ## 5 F 9 NA ## 6 E NA 29
Nhiều cặp khóa
Cuối cùng nhưng không kém phần quan trọng, chúng ta có thể có nhiều khóa trong tập dữ liệu của mình. Hãy xem xét tập dữ liệu sau đây, trong đó chúng ta có các năm và danh sách các sản phẩm mà khách hàng đã mua. Ảnh chụp màn hình bên dưới hiển thị hai bảng và các cột ID và năm, cùng nhau xác định một hàng.
Nếu ta chỉ kết hợp hai bảng dựa trên ID, thì mỗi năm sẽ được so khớp với mỗi năm khác và số lượng hàng sẽ tăng lên đáng kể. Để khắc phục tình trạng này, ta có thể truyền hai biến cặp khóa, đó là ID và năm, xuất hiện trong cả hai tập dữ liệu. Ta có thể sử dụng đoạn mã sau để hợp nhất bảng 1 và bảng 2:
df_primary <- tribble( ~ID, ~year, ~items, "A", 2015,3, "A", 2016,7, "A", 2017,6, "B", 2015,4, "B", 2016,8, "B", 2017,7, "C", 2015,4, "C", 2016,6, "C", 2017,6) df_secondary <- tribble( ~ID, ~year, ~prices, "A", 2015,9, "A", 2016,8, "A", 2017,12, "B", 2015,13, "B", 2016,14, "B", 2017,6, "C", 2015,15, "C", 2016,15, "C", 2017,13) left_join(df_primary, df_secondary, by = c('ID', 'year'))
Đầu ra:
## # A tibble: 9 x 4 ## ID year items prices ## <chr> <dbl> <dbl> <dbl> ## 1 A 2015 3 9 ## 2 A 2016 7 8 ## 3 A 2017 6 12 ## 4 B 2015 4 13 ## 5 B 2016 8 14 ## 6 B 2017 7 6 ## 7 C 2015 4 15 ## 8 C 2016 6 15 ## 9 C 2017 6 13
Từ phiên bản dplyr 1.1.0 (tháng 1 năm 2023), cùng một khóa có thể được viết dưới dạng join_by(ID, year), và dplyr hiện cảnh báo về các kết quả khớp nhiều-nhiều không mong muốn, vì dplyr 1.1.0 tham gia thông báo giải thích.
Chức năng làm sạch dữ liệu trong R
Việc hợp nhất chỉ giải quyết được một nửa vấn đề, vì bảng kết hợp vẫn cần được định dạng lại. Sau đây là bốn hàm quan trọng để làm sạch dữ liệu:
| Chức năng | Mục tiêu | Lập luận |
|---|---|---|
| tập trung() | Chuyển đổi dữ liệu từ rộng sang dài | (dữ liệu, khóa, giá trị, na.rm = FALSE) |
| lây lan() | Chuyển đổi dữ liệu từ dài sang rộng | (dữ liệu, khóa, giá trị) |
| chia() | Chia một biến thành hai biến. | (data, col, into, sep = “”, remove = TRUE) |
| đoàn kết() | Kết hợp hai biến thành một. | (data, col, conc, sep = “”, remove = TRUE) |
Ghi chú phiên bản: Các hàm `gather()` và `spread()` đã được thay thế bằng `pivot_longer()` và `pivot_wider()` trong tidyr 1.0.0, và hàm `separate()` được thay thế bằng nhóm hàm `separate_wider_delim()` trong tidyr 1.3.0. Các hàm đã được thay thế vẫn chạy, vì vậy mọi ví dụ bên dưới đều hoạt động, nhưng mã mới nên ưu tiên các nhóm hàm mới hơn được hiển thị trong phần mô tả. hình ảnh xoay gọn gàng.unit() vẫn đang được sử dụng.
Chúng tôi sử dụng gói tidyr, một phần của bộ sưu tập tidyverse, để thao tác, làm sạch và trực quan hóa dữ liệu. Nếu R được cài đặt cùng với Anaconda, gói này đã có sẵn từ đó. https://anaconda.org/r/r-tidyr.
Nếu chưa cài đặt, hãy nhập lệnh sau để cài đặt tidyr:
install.packages("tidyr")
tập trung()
Mục tiêu của hàm gather() là chuyển đổi dữ liệu từ định dạng rộng sang định dạng dài.
cú pháp
gather(data, key, value, na.rm = FALSE) Arguments: -data: The data frame used to reshape the dataset -key: Name of the new column created -value: Select the columns used to fill the key column -na.rm: Remove missing values. FALSE by default
Ví dụ
Dưới đây, chúng ta có thể hình dung khái niệm về resha.ping Từ bảng rộng sang bảng dài. Chúng ta muốn tạo một cột duy nhất có tên là "tăng trưởng", được điền bởi các hàng của các biến quý. Hình dưới đây cho thấy bảng rộng ở bên trái và bảng dài đã được định hình lại ở bên phải.
library(tidyr) # Create a messy dataset messy <- data.frame( country = c("A", "B", "C"), q1_2017 = c(0.03, 0.05, 0.01), q2_2017 = c(0.05, 0.07, 0.02), q3_2017 = c(0.04, 0.05, 0.01), q4_2017 = c(0.03, 0.02, 0.04)) messy
Đầu ra:
## country q1_2017 q2_2017 q3_2017 q4_2017 ## 1 A 0.03 0.05 0.04 0.03 ## 2 B 0.05 0.07 0.05 0.02 ## 3 C 0.01 0.02 0.01 0.04
# Reshape the data
tidier <-messy %>%
gather(quarter, growth, q1_2017:q4_2017)
tidier
Đầu ra:
## country quarter growth ## 1 A q1_2017 0.03 ## 2 B q1_2017 0.05 ## 3 C q1_2017 0.01 ## 4 A q2_2017 0.05 ## 5 B q2_2017 0.07 ## 6 C q2_2017 0.02 ## 7 A q3_2017 0.04 ## 8 B q3_2017 0.05 ## 9 C q3_2017 0.01 ## 10 A q4_2017 0.03 ## 11 B q4_2017 0.02 ## 12 C q4_2017 0.04
Trong hàm gather(), chúng ta tạo ra hai biến mới là quarter và growth, bởi vì tập dữ liệu gốc của chúng ta chỉ có một biến nhóm là country và các cặp khóa-giá trị. Trong tidyr 1.0.0 trở lên, thao tác định hình lại tương tự được viết là pivot_longer(messy, cols = q1_2017:q4_2017, names_to = “quarter”, values_to = “growth”).
lây lan()
Hàm spread() thực hiện thao tác ngược lại với hàm gather().
cú pháp
spread(data, key, value) arguments: data: The data frame used to reshape the dataset key: Column to reshape long to wide value: Rows used to fill the new column
Ví dụ
Chúng ta có thể chuyển đổi tập dữ liệu gọn gàng trở lại thành dạng lộn xộn bằng hàm spread().
# Reshape the data
messy_1 <- tidier %>%
spread(quarter, growth)
messy_1
Đầu ra:
## country q1_2017 q2_2017 q3_2017 q4_2017 ## 1 A 0.03 0.05 0.04 0.03 ## 2 B 0.05 0.07 0.05 0.02 ## 3 C 0.01 0.02 0.01 0.04
Công thức tương đương hiện đại là pivot_wider(tidier, names_from = quarter, values_from = growth).
chia()
Hàm `separate()` tách một cột thành hai cột dựa trên dấu phân cách. Hàm này hữu ích trong trường hợp biến là ngày tháng. Phân tích của chúng ta có thể cần tập trung vào tháng và năm, và chúng ta muốn tách cột đó thành hai biến mới.
cú pháp
separate(data, col, into, sep= "", remove = TRUE) arguments: -data: The data frame used to reshape the dataset -col: The column to split -into: The name of the new variables -sep: Indicates the symbol used that separates the variable, i.e.: "-", "_", "&" -remove: Remove the old column. By default sets to TRUE.
Ví dụ
Chúng ta có thể tách quý khỏi năm trong tập dữ liệu gọn gàng hơn bằng cách áp dụng hàm riêng biệt().
separate_tidier <-tidier %>% separate(quarter, c("Qrt", "year"), sep ="_") head(separate_tidier)
Đầu ra:
## country Qrt year growth ## 1 A q1 2017 0.03 ## 2 B q1 2017 0.05 ## 3 C q1 2017 0.01 ## 4 A q2 2017 0.05 ## 5 B q2 2017 0.07 ## 6 C q2 2017 0.02
đoàn kết()
Hàm unite() nối hai cột thành một cột.
cú pháp
unite(data, col, conc ,sep= "", remove = TRUE) arguments: -data: The data frame used to reshape the dataset -col: Name of the new column -conc: Name of the columns to concatenate -sep: Indicates the symbol used that unites the variable, i.e: "-", "_", "&" -remove: Remove the old columns. By default, sets to TRUE
Ví dụ
Trong ví dụ trên, chúng ta đã tách quý khỏi năm. Vậy nếu muốn gộp chúng lại thì sao? Chúng ta sử dụng đoạn mã sau:
unit_tidier <- separate_tidier %>%
unite(Quarter, Qrt, year, sep ="_")
head(unit_tidier)
Đầu ra:
## country Quarter growth ## 1 A q1_2017 0.03 ## 2 B q1_2017 0.05 ## 3 C q1_2017 0.01 ## 4 A q2_2017 0.05 ## 5 B q2_2017 0.07 ## 6 C q2_2017 0.02
Khung dữ liệu đã được định hình lại hiện đã sẵn sàng cho các bước mô hình hóa được trình bày trong phần còn lại của bài viết. Chuỗi bài hướng dẫn về R.







