Hướng dẫn Dplyr: Hợp nhất và nối dữ liệu trong R với các ví dụ
Giới thiệu về Phân tích Dữ liệu
Phân tích dữ liệu có thể được chia thành ba phần:
- Khai thác: Đầ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.
Một trong những thách thức quan trọng 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 xử lý dữ liệu không đầy đủ, chính xác và nghiêm ngặt thì mô hình sẽ không hoạt động chính xác.
R Dplyr
R có một thư viện tên là dplyr để giúp chuyển đổi dữ liệu. Thư viện dplyr về cơ bản được tạo xung quanh bốn hàm để thao tác dữ liệu và năm động từ để làm sạch dữ liệu. Sau đó, chúng ta có thể sử dụng thư viện ggplot để phân tích và trực quan hóa dữ liệu.
Chúng ta sẽ tìm hiểu cách sử dụng thư viện dplyr để thao tác một Khung dữ liệu.
Hợp nhất dữ liệu với R 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.
Tham gia Dplyr
Sau đây là bốn loại liên kết quan trọng được sử dụng trong dplyr để hợp nhất hai tập dữ liệu:
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 | dữ liệu, nguồn gốc, đích đến, by = “ID” | điểm đi, điểm đến, 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 | dữ liệu, nguồn gốc, đích đến, by = “ID” | điểm đi, điểm đến, by = c(“ID”, “ID2”) |
bên trong_join() | Hợp nhất hai tập dữ liệu. Loại trừ tất cả các hàng chưa khớp | dữ liệu, nguồn gốc, đích đến, by = “ID” | điểm đi, điểm đến, by = c(“ID”, “ID2”) |
full_join() | Hợp nhất hai tập dữ liệu. Giữ tất cả các quan sát | dữ liệu, nguồn gốc, đích đến, by = “ID” | điểm đi, điểm đến, by = c(“ID”, “ID2”) |
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 tôi xây dựng hai bộ dữ liệu. Bảng 1 chứa hai biến, ID và y, trong khi Bảng 2 tập hợp ID và z. Trong mỗi tình huống chúng ta cần có 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 đổi. Hàm sẽ tìm kiếm các giá trị giống nhau trong cả hai bảng và liên kết các giá trị trả về ở bên phải bảng 1.
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(). Chúng ta có thể thấy trong hình bên dưới rằng cặp khóa khớp hoàn hảo với các hàng A, B, C và D từ cả hai tập dữ liệu. Tuy nhiên, E và F vẫn còn sót lại. Chúng ta xử lý hai quan sát này như thế nào? Với left_join(), chúng ta sẽ giữ tất cả các biến trong bảng gốc và không xem xét các biến không có cặp khóa trong bảng đích. Trong ví dụ của chúng tôi, biến E không tồn tại trong bảng 1. Do đó, hàng sẽ bị loại bỏ. Biến F xuất phát từ bảng gốc; nó sẽ được giữ sau left_join() và trả về NA trong cột z. Hình bên dưới mô phỏng những gì sẽ xảy ra với left_join().
Ví dụ về dplyr 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
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()
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 bên trong_join()
Khi chúng tôi chắc chắn 100% rằng hai bộ dữ liệu không khớp nhau, chúng tôi có thể cân nhắc quay lại có thể hàng tồn tại trong cả hai tập dữ liệu. Điều này có thể thực hiện được khi chúng ta cần một tập dữ liệu sạch hoặc khi chúng ta không muốn gán các giá trị bị thiếu bằng giá trị trung bình hoặc trung vị.
Inner_join() sẽ trợ giúp. Hàm này loại trừ các hàng chưa khớp.
Ví dụ về dplyr Inner_join()
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ị bị thiếu bằng NA.
Ví dụ về dplyr full_join()
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ó năm hoặc danh sách các sản phẩm mà khách hàng đã mua.
Nếu chúng ta thử hợp nhất cả hai bảng, R sẽ báo lỗi. Để khắc phục tình trạng này, chúng 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. Chúng ta có thể sử dụng mã sau để hợp nhất table1 và table 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
Chức năng làm sạch dữ liệu trong R
Sau đây là bốn chức năng quan trọng để sắp xếp (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 | (dữ liệu, col, vào, sep= “”, xóa = TRUE) |
đơn vị() | Đơn vị hai biến thành một | (dữ liệu, col, conc ,sep= “”, xóa = TRUE) |
Chúng tôi sử dụng thư viện gọn gàng. Thư viện này thuộc bộ sưu tập của thư viện để thao tác, làm sạch và trực quan hóa dữ liệu. Nếu chúng ta cài đặt R bằng anaconda thì thư viện đã được cài đặt sẵn. Chúng ta có thể tìm thấy thư viện ở đây, 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 tidyr : install.packages("tidyr")
tập trung()
Mục tiêu của hàm thu thập () là chuyển đổi dữ liệu từ rộng sang 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 định hình lại từ rộng đến dài. Chúng tôi muốn tạo một cột có tên là tăng trưởng, được điền bởi các hàng của biến quý.
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 thu thập (), chúng tôi tạo hai biến quý và tăng trưởng mới vì tập dữ liệu ban đầu của chúng tôi có một biến nhóm: tức là quốc gia và các cặp khóa-giá trị.
lây lan()
Hàm spread() thực hiện ngược lại với hàm thu thập.
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ể định hình lại tập dữ liệu gọn gàng hơn trở lại lộn xộn với 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
chia()
Hàm riêng biệt () chia một cột thành hai theo dấu phân cách. Hàm này hữu ích trong một số trường hợp biến là ngày. Phân tích của chúng tôi có thể yêu cầu tập trung vào tháng và năm và chúng tôi 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 unity() nối hai cột thành một.
cú pháp
unit(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. Nếu chúng ta muốn hợp nhất chúng thì sao. Chúng ta sử dụng 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
Tổng kết
- Phân tích dữ liệu có thể được chia thành ba phần: Trích xuất, Chuyển đổi và Trực quan hóa.
- R có một thư viện tên là dplyr để giúp chuyển đổi dữ liệu. Thư viện dplyr về cơ bản được tạo xung quanh bốn hàm để thao tác dữ liệu và năm động từ để làm sạch dữ liệu.
- 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. 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.
- Cái hay của dplyr là nó xử lý bốn loại kết nối tương tự như SQL:
- chỗ nối bên trái() – Để hợp nhất hai tập dữ liệu và giữ tất cả các quan sát từ bảng gốc.
- phải_join() – Để hợp nhất hai tập dữ liệu và giữ tất cả các quan sát từ bảng đích.
- bên trong_join() – Để hợp nhất hai tập dữ liệu và loại trừ tất cả các hàng không khớp.
- full_join() – Để hợp nhất hai tập dữ liệu và giữ tất cả các quan sát.
- Sử dụng Thư viện tidyr, bạn có thể chuyển đổi một tập dữ liệu bằng các hàm sau:
- tập trung(): Chuyển đổi dữ liệu từ rộng sang dài.
- lây lan(): Chuyển đổi dữ liệu từ dài sang rộng.
- chia(): Chia một biến thành hai.
- đơn vị(): Hợp nhất hai biến thành một.