วิธีระบุชื่อคอลัมน์สำหรับ x และ y เมื่อเข้าร่วมใน dplyr


91

ฉันมีเฟรมข้อมูลสองเฟรมที่ฉันต้องการเข้าร่วมโดยใช้ dplyr หนึ่งคือกรอบข้อมูลที่มีชื่อ

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

กรอบข้อมูลอื่นประกอบด้วยคลังข้อมูลชื่อ Kantrowitz รุ่นที่ล้างแล้วโดยระบุเพศ นี่คือตัวอย่างเล็กน้อย:

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

โดยพื้นฐานแล้วฉันต้องการค้นหาเพศของชื่อจากtest_dataตารางโดยใช้kantrowitzตาราง เนื่องจากฉันจะสรุปสิ่งนี้เป็นฟังก์ชันencode_genderฉันจึงไม่รู้ชื่อคอลัมน์ในชุดข้อมูลที่จะใช้ดังนั้นฉันจึงไม่สามารถรับประกันได้ว่าจะเป็นnameเช่นkantrowitz$nameนั้น

ในฐาน RI จะทำการผสานด้วยวิธีนี้:

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

ที่ส่งคืนผลลัพธ์ที่ถูกต้อง:

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

แต่ฉันต้องการทำสิ่งนี้ใน dplyr เพราะฉันใช้แพ็คเกจนั้นสำหรับการจัดการข้อมูลอื่น ๆ ทั้งหมดของฉัน byตัวเลือกdplyr สำหรับ*_joinฟังก์ชันต่างๆช่วยให้ฉันระบุชื่อคอลัมน์ได้เพียงชื่อเดียว แต่ฉันต้องระบุสองคอลัมน์ ฉันกำลังมองหาสิ่งนี้:

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

วิธีการเข้าร่วมประเภทนี้โดยใช้ dplyr คืออะไร?

(ไม่เป็นไรว่าคลังข้อมูล Kantrowitz เป็นวิธีที่ไม่ดีในการระบุเพศฉันกำลังดำเนินการปรับปรุงให้ดีขึ้น แต่ฉันต้องการให้สิ่งนี้ได้ผลก่อน)


3
ตอนนี้คุณทำไม่ได้ แต่อยู่ในรายการสิ่งที่ต้องทำ: github.com/hadley/dplyr/issues/177
hadley

คำตอบ:


153

คุณสมบัตินี้ถูกเพิ่มใน dplyr v0.3 ตอนนี้คุณสามารถส่งเวกเตอร์อักขระที่มีชื่อไปยังbyอาร์กิวเมนต์ในleft_join(และฟังก์ชันการเข้าร่วมอื่น ๆ ) เพื่อระบุคอลัมน์ที่จะเข้าร่วมในแต่ละเฟรมข้อมูล ด้วยตัวอย่างที่ให้ไว้ในคำถามเดิมรหัสจะเป็น:

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

13
แก้ไขสิ่งนี้ใช้ได้ในกรณีทั่วไปเช่นกัน: left_join(data_a, data_b, by = c("a.first" = "b.first", "a.second" = "b.second", "a.third" = "b.third"))?
davidski

by =เป็นตัวเลือก คุณทำได้left_join(test_data, kantrowitz, c("first_name" = "name"))
Pranay Aryal

11
นั่นเป็นความจริงของอาร์กิวเมนต์ใด ๆ ต่อฟังก์ชัน แต่โดยทั่วไปแล้วฉันพบว่าเป็นการดีกว่าที่จะชัดเจนโดยใช้อาร์กิวเมนต์ที่ตั้งชื่อแทนที่จะจับคู่ตำแหน่งในกรณีนี้
Lincoln Mullen

5

นี่เป็นวิธีแก้ปัญหามากกว่าวิธีแก้ปัญหาจริง คุณสามารถสร้างวัตถุใหม่test_dataด้วยชื่อคอลัมน์อื่น:

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>

ฉันคิดว่าการเปลี่ยนชื่อทำให้เกิดการคัดลอกซึ่งอาจเป็นวิธีที่ dplyr หลีกเลี่ยงและทำให้คุณทำแทน
joran

2
อย่างน้อยใน 0.1.2 คุณจะสามารถทำได้select(test_data, first_name = name)และจะทำสำเนาตื้น ๆ เท่านั้น
hadley

1
ใช้data.table::setnames?
ฮิวจ์

2
โซลูชัน select (test_data, first_name = name) ไม่ทำงาน ณ มิถุนายน 2014
userJT
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.