Hợp nhất các khung dữ liệu trong R: So khớp toàn bộ và một phần
⚡ Tóm tắt thông minh
Việc hợp nhất các khung dữ liệu trong R kết hợp hai bảng dựa trên một hoặc nhiều cột khóa chung. Hàm merge() bao gồm các phép nối trong, nối trái, nối phải và nối đầy đủ, và hướng dẫn này minh họa cả phép nối khớp hoàn toàn và khớp một phần.

Rất thường xuyên, chúng tôi có dữ liệu từ nhiều nguồn. Để thực hiện phân tích, chúng ta cần hợp nhất hai khung dữ liệu cùng với một hoặc nhiều biến khóa chung.
Các loại phép hợp nhất (ghép nối) trong R
Trước khi xem xét các ví dụ, điều hữu ích là cần biết rằng hàm merge() thực hiện mọi loại phép nối mà người dùng SQL mong đợi. Hành vi này được điều khiển bởi các đối số all, all.x và all.y chứ không phải bởi một tên hàm khác.
| Tham gia loại | Các hàng được giữ | cuộc gọi merge() | tương đương dplyr |
|---|---|---|---|
| Phép nối trong (mặc định) | Chỉ những khóa xuất hiện trong cả hai khung hình | hợp nhất(x, y, theo = “k”) | inner_join(x, y, by = “k”) |
| Kết nối bên ngoài bên trái | Tất cả các hàng của x, NA ở những nơi y không có giá trị khớp. | merge(x, y, by = “k”, all.x = TRUE) | left_join(x, y, by = “k”) |
| Tham gia bên ngoài bên phải | Tất cả các hàng của y, NA ở những nơi x không có giá trị khớp | merge(x, y, by = “k”, all.y = TRUE) | right_join(x, y, by = “k”) |
| Tham gia đầy đủ bên ngoài | Mỗi hàng từ cả hai khung | merge(x, y, by = “k”, all = TRUE) | full_join(x, y, by = “k”) |
| Tham gia chéo | Mỗi sự kết hợp của các hàng | hợp nhất(x, y, theo = NULL) | cross_join(x, y) |
Có hai chi tiết đáng nhớ trước cuộc gọi đầu tiên:
- Việc bỏ qua tham số `by` khiến R hợp nhất các tên cột mà hai khung hình chia sẻ, điều này hiếm khi là điều bạn muốn.
- Hàm merge() sắp xếp kết quả theo cột khóa; truyền tham số sort = FALSE để giữ nguyên thứ tự ban đầu.
Toàn trận đấu
Một phép so khớp hoàn toàn chỉ trả về các giá trị có tương ứng trong bảng đích. Các hàng không khớp sẽ bị loại bỏ khỏi khung dữ liệu mới. Ngược lại, một phép so khớp một phần sẽ giữ lại các hàng đó và điền các cột bị thiếu bằng NA.
Chúng ta sẽ thấy một cách đơn giản tham gia bên trong. Từ khóa kết nối bên trong chọn các bản ghi có giá trị trùng khớp trong cả hai bảng. Để nối hai tập dữ liệu, chúng ta có thể sử dụng hàm merge(). Chúng ta sẽ sử dụng ba đối số:
merge(x, y, by.x = x, by.y = y) Arguments: -x: The origin data frame -y: The data frame to merge -by.x: The column used for merging in x data frame. Column x to merge on -by.y: The column used for merging in y data frame. Column y to merge on
Ví dụ:
Tạo tập dữ liệu đầu tiên với các biến
- họ
- quốc tịch
Tạo tập dữ liệu thứ hai với các biến
- họ
- phim
Biến khóa chung là họ. Chúng ta có thể hợp nhất cả hai. khung dữ liệu và kiểm tra xem kích thước có phải là 7×3 hay không.
Chúng tôi thêm stringsAsFactors=FALSE vào khung dữ liệu vì chúng tôi không muốn R để chuyển đổi các chuỗi thành một yếu tố; biến này nên giữ nguyên kiểu dữ liệu là một vectơ ký tự. Từ phiên bản R 4.0.0 trở đi, đây đã là giá trị mặc định cho data.frame(), vì vậy đối số này là tùy chọn trong mã mới và không gây hại trong mã cũ.
# Create origin dataframe( producers <- data.frame( surname = c("Spielberg","Scorsese","Hitchcock","Tarantino","Polanski"), nationality = c("US","US","UK","US","Poland"), stringsAsFactors=FALSE) # Create destination dataframe movies <- data.frame( surname = c("Spielberg", "Scorsese", "Hitchcock", "Hitchcock", "Spielberg", "Tarantino", "Polanski"), title = c("Super 8", "Taxi Driver", "Psycho", "North by Northwest", "Catch Me If You Can", "Reservoir Dogs","Chinatown"), stringsAsFactors=FALSE) # Merge two datasets m1 <- merge(producers, movies, by.x = "surname") m1 dim(m1)
Đầu ra:
surname nationality title 1 Hitchcock UK Psycho 2 Hitchcock UK North by Northwest 3 Polanski Poland Chinatown 4 Scorsese US Taxi Driver 5 Spielberg US Super 8 6 Spielberg US Catch Me If You Can 7 Tarantino US Reservoir Dogs
Hãy hợp nhất các khung dữ liệu khi các biến khóa chung có tên khác nhau.
Chúng ta đổi họ thành tên trong khung dữ liệu phim. Chúng tôi sử dụng hàm giống hệt nhau (x1, x2) để kiểm tra xem cả hai khung dữ liệu có giống nhau hay không.
# Change name of ` movies ` dataframe colnames(movies)[colnames(movies) == 'surname'] <- 'name' # Merge with different key value m2 <- merge(producers, movies, by.x = "surname", by.y = "name") # Print head of the data head(m2)
Đầu ra:
##surname nationality title ## 1 Hitchcock UK Psycho ## 2 Hitchcock UK North by Northwest ## 3 Polanski Poland Chinatown ## 4 Scorsese US Taxi Driver ## 5 Spielberg US Super 8 ## 6 Spielberg US Catch Me If You Can
# Check if data are identical
identical(m1, m2)
Đầu ra:
## [1] TRUE
Điều này cho thấy thao tác hợp nhất được thực hiện ngay cả khi tên cột khác nhau.
Trận đấu một phần
Phép nối trong ở trên đã âm thầm loại bỏ bất cứ thứ gì không có phần tương ứng. Không có gì đáng ngạc nhiên khi hai dataframe không có cùng các biến khóa chung. Trong kết hợp đầy đủ, khung dữ liệu trả về có thể các hàng được tìm thấy trong cả khung dữ liệu x và y. Với sáp nhập một phần, có thể giữ các hàng không có hàng trùng khớp trong khung dữ liệu khác. Các hàng này sẽ có NA trong các cột thường chứa các giá trị từ y. Chúng ta có thể làm điều đó bằng cách đặt all.x= TRUE.
Ví dụ, chúng ta có thể thêm một nhà sản xuất mới, Lucas, vào khung dữ liệu nhà sản xuất mà không cần tham chiếu phim trong khung dữ liệu phim. Nếu ta đặt all.x = FALSE, R sẽ chỉ kết hợp các giá trị khớp nhau trong cả hai tập dữ liệu. Trong trường hợp của chúng ta, nhà sản xuất Lucas sẽ không được kết hợp vào kết quả, vì anh ta bị thiếu trong một tập dữ liệu.
Hãy xem thứ nguyên của từng đầu ra khi chúng ta chỉ định all.x= TRUE và khi không.
# Create a new producer add_producer <- c('Lucas', 'US') # Append it to the ` producer` dataframe producers <- rbind(producers, add_producer) # Use a partial merge m3 <-merge(producers, movies, by.x = "surname", by.y = "name", all.x = TRUE) m3
Đầu ra:
Dưới đây là kết quả hiển thị trên bảng điều khiển cho thấy hàng Lucas bổ sung, với NA đại diện cho tiêu đề phim bị thiếu.
# Compare the dimension of each data frame
dim(m1)
Đầu ra:
## [1] 7 3
dim(m2)
Đầu ra:
## [1] 7 3
dim(m3)
Đầu ra:
## [1] 8 3
Như chúng ta thấy, khung dữ liệu mới có kích thước 8×3, so với 7×3 của m1 và m2. R điền cột tiêu đề bằng NA cho Lucas, nhà sản xuất không có hàng tương ứng trong khung dữ liệu phim.
So sánh hàm `merge()` và `dplyr` trong R.
R cơ bản giải quyết mọi phép nối bằng một hàm và một tập hợp các cờ. dplyr Thay vào đó, gói này gán cho mỗi phép nối một động từ riêng, điều mà nhiều nhóm thấy dễ đọc hơn trong quy trình xử lý dữ liệu.
| Tiêu chí | Hợp nhất cơ sở() | dplyr tham gia |
|---|---|---|
| Chọn điểm nối | tất cả.x / tất cả.y / tất cả các lá cờ | Được đặt tên trong động từ: left_join(), full_join() |
| Thứ tự hàng | Sắp xếp theo khóa trừ khi sort = FALSE | Thứ tự của bảng bên trái được giữ nguyên. |
| Tốc độ trên khung hình lớn | Chậm hơn | Nói chung là nhanh hơn |
| Cột khóa bị thiếu | Lỗi xảy ra muộn hoặc hợp nhất trên các cột sai. | Lỗi ngay lập tức |
| Sự phụ thuộc | Base R, không cần cài đặt gì thêm | Yêu cầu gói dplyr. |
Hai phép hợp nhất được hiển thị ở trên được dịch trực tiếp thành các động từ dplyr:
library(dplyr) # Same inner join as merge(producers, movies, by.x = "surname", by.y = "name") m4 <- inner_join(producers, movies, by = c("surname" = "name")) # Same partial merge as all.x = TRUE m5 <- left_join(producers, movies, by = c("surname" = "name"))
Hàm `merge()` cơ bản là lựa chọn an toàn hơn bên trong một gói không nên có bất kỳ phụ thuộc nào. `dplyr` là lựa chọn tốt hơn trong phân tích tương tác, nơi khả năng đọc hiểu và tốc độ quan trọng hơn.
Các lỗi hợp nhất thường gặp trong R và cách khắc phục chúng
Hầu hết các vấn đề khi hợp nhất đều thể hiện qua số lượng hàng không như mong đợi chứ không phải thông báo lỗi, vì vậy việc kiểm tra dim() sau mỗi lần nối là một thói quen nên xây dựng.
- Kết quả có nhiều hàng hơn cả dữ liệu đầu vào lẫn dữ liệu đầu vào. Một khóa lặp lại trong cả hai khung sẽ tạo ra phép nối nhiều-nhiều, và R trả về mọi tổ hợp. Kiểm tra các khóa bằng table(duplicated(x$k)) trước khi hợp nhất.
- Kết quả trống. Các cột khóa thường khác nhau về kiểu dữ liệu, hoặc một trong số chúng có chứa khoảng trắng ở cuối. Hãy chạy hàm str() trên cả hai khung và làm sạch khóa bằng hàm trimws() trước khi hợp nhất.
- Các cột được trả về dưới dạng title.x và title.y. Cả hai khung đều chứa một cột không phải khóa có cùng tên. Truyền hậu tố = c(“_producer”, “_film”) để làm rõ nguồn gốc.
- Các hàng không còn được sắp xếp theo thứ tự ban đầu nữa. Hàm merge() mặc định sắp xếp theo khóa. Thêm sort = FALSE, hoặc sử dụng một loại rõ ràng sau đó
- Một sự so sánh quan trọng đã thất bại ở các yếu tố. So sánh các ký tự, không phải các cấp độ yếu tố: hãy bọc khóa trong as.character() trước khi hợp nhất các khung được tạo theo các thiết lập mặc định cũ của R.
Khi cần thực hiện cùng một thao tác hợp nhất nhiều lần, hãy gói nó trong một khối lệnh. chức năng do người dùng xác định Vì vậy, các lập luận không thể thay đổi giữa các lần chạy.

