Làm thế nào để chỉ định tên của các cột cho x và y khi tham gia vào dplyr?


89

Tôi có hai khung dữ liệu mà tôi muốn kết hợp bằng dplyr. Một là khung dữ liệu chứa tên.

test_data <- data.frame(first_name = c("john", "bill", "madison", "abby", "zzz"),
                        stringsAsFactors = FALSE)

Khung dữ liệu khác chứa phiên bản đã được làm sạch của kho dữ liệu tên Kantrowitz, xác định giới tính. Đây là một ví dụ nhỏ nhất:

kantrowitz <- structure(list(name = c("john", "bill", "madison", "abby", "thomas"), gender = c("M", "either", "M", "either", "M")), .Names = c("name", "gender"), row.names = c(NA, 5L), class = c("tbl_df", "tbl", "data.frame"))

Về cơ bản, tôi muốn tra cứu giới tính của tên từ test_databảng bằng cách sử dụng kantrowitzbảng. Bởi vì tôi sẽ trừu tượng hóa điều này thành một hàm encode_gender, tôi sẽ không biết tên của cột trong tập dữ liệu sẽ được sử dụng, và vì vậy tôi không thể đảm bảo rằng nó sẽ namenhư vậy kantrowitz$name.

Trong RI cơ sở sẽ thực hiện hợp nhất theo cách này:

merge(test_data, kantrowitz, by.x = "first_names", by.y = "name", all.x = TRUE)

Điều đó trả về đầu ra chính xác:

  first_name gender
1       abby either
2       bill either
3       john      M
4    madison      M
5        zzz   <NA>

Nhưng tôi muốn làm điều này trong dplyr vì tôi đang sử dụng gói đó cho tất cả các thao tác dữ liệu khác của mình. byTùy chọn dplyr cho các *_joinchức năng khác nhau chỉ cho phép tôi chỉ định một tên cột, nhưng tôi cần chỉ định hai. Tôi đang tìm kiếm một cái gì đó như thế này:

library(dplyr)
# either
left_join(test_data, kantrowitz, by.x = "first_name", by.y = "name")
# or
left_join(test_data, kantrowitz, by = c("first_name", "name"))

Cách để thực hiện kiểu tham gia này bằng dplyr là gì?

(Đừng bận tâm rằng kho tài liệu Kantrowitz là một cách tồi để xác định giới tính. Tôi đang làm việc để triển khai tốt hơn, nhưng tôi muốn điều này hoạt động trước đã.)


3
Bạn có thể không hiện, nhưng đó là về để làm danh sách: github.com/hadley/dplyr/issues/177
hadley

Câu trả lời:


148

Tính năng này đã được thêm vào trong dplyr v0.3. Bây giờ bạn có thể truyền một vectơ ký tự đã đặt tên cho byđối số trong left_join(và các hàm nối khác) để chỉ định cột nào sẽ tham gia trong mỗi khung dữ liệu. Với ví dụ được đưa ra trong câu hỏi ban đầu, mã sẽ là:

left_join(test_data, kantrowitz, by = c("first_name" = "name"))

13
chỉnh sửa Điều này cũng hoạt động trong trường hợp chung left_join(data_a, data_b, by = c("a.first" = "b.first", "a.second" = "b.second", "a.third" = "b.third")):?
davidski

by =tùy chọn. Bạn có thể làmleft_join(test_data, kantrowitz, c("first_name" = "name"))
Pranay Aryal

11
Điều đó đúng với bất kỳ đối số nào đối với một hàm. Nhưng tôi thường thấy tốt hơn là rõ ràng bằng cách sử dụng các đối số được đặt tên hơn là đối sánh vị trí trong trường hợp này.
Lincoln Mullen

5

Đây là một cách giải quyết hơn là một giải pháp thực sự. Bạn có thể tạo một đối tượng mới test_datavới tên cột khác:

left_join("names<-"(test_data, "name"), kantrowitz, by = "name")

     name gender
1    john      M
2    bill either
3 madison      M
4    abby either
5     zzz   <NA>

Tôi nghĩ rằng đổi tên sẽ tạo ra một bản sao, đó có thể là cách mà dplyr tránh nó và khiến bạn phải làm điều đó thay thế.
joran

2
Trong 0.1.2, ít nhất bạn sẽ có thể làm được select(test_data, first_name = name)và điều đó sẽ chỉ tạo ra một bản sao cạn.
hadley

1
Sử dụng data.table::setnames?
Hugh

2
giải pháp chọn (test_data, first_name = name) không hoạt động kể từ tháng 6 năm 2014
userJT
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.