2015-01-24 14 views
12

Làm cách nào để nối 2 bảng bằng cách sử dụng * _join() từ dplyr, khi tên biến tham gia khác nhau và được lưu trữ trong một biến khác?R: Đánh giá tiêu chuẩn cho * _join (dplyr)

ví dụ:

df1 = data_frame(x1 = 1:10,y1 = 21:30) 
df2 = data_frame(x2 = 6:15,y2 = 26:35) 
df3 = data_frame(x1 = 6:15,y2 = 26:35) 

var1 = "x1" 
var2 = "x2" 

df1 %>% left_join(df3,by=c(var1)) # #1 works 

nhưng điều này cho lỗi -

df1 %>% left_join(df2,by=c(var1 = var2)) # #2 doesn't work 
Error: cannot join on columns 'x2' x 'var1': index out of bounds 

đáng ngạc nhiên, công trình này -

df1 %>% left_join(df2,by=c("x1" = var2)) # #3 works 

Trả lời

17

Vấn đề ở đây là bạn phải cung cấp một vector tên nếu cột chung có tên gọi khác nhau trong data.frames. Hãy xem những gì sẽ xảy ra trong ví dụ của bạn:

Nó hoạt động khi bạn cung cấp tên trực tiếp:

df1 %>% left_join(df2, by = c("x1" = "x2")) 
#Source: local data frame [10 x 3] 
# 
# x1 y1 y2 
#1 1 21 NA 
#2 2 22 NA 
#3 3 23 NA 
#4 4 24 NA 
#5 5 25 NA 
#6 6 26 26 
#7 7 27 27 
#8 8 28 28 
#9 9 29 29 
#10 10 30 30 

Và vector tên bạn cung cấp là:

c("x1" = "x2") 
# x1 
#"x2" 

Bây giờ nếu bạn sử dụng vectơ nhân vật, các thay đổi về tên có tên là:

var1 = "x1" 
var2 = "x2" 

c(var1 = var2) 
#var1    # <~~ this is why it doesn't work 
#"x2" 

Tôi không biết nếu có cách "sạch" để giải quyết vấn đề này trong dply r hiện tại. Một cách giải quyết là tinh chỉnh sau đây để xây dựng các vector được đặt tên theo yêu cầu:

df1 %>% left_join(df2, by = setNames(var2, var1)) 
#Source: local data frame [10 x 3] 
# 
# x1 y1 y2 
#1 1 21 NA 
#2 2 22 NA 
#3 3 23 NA 
#4 4 24 NA 
#5 5 25 NA 
#6 6 26 26 
#7 7 27 27 
#8 8 28 28 
#9 9 29 29 
#10 10 30 30 

này hoạt động bởi vì:

setNames(var2, var1) 
# x1 
#"x2" 

Hy vọng nó giúp.


Lưu ý: bạn có thể làm tương tự với names<- như vậy:

df1 %>% left_join(df2, by = `names<-`(var2, var1)) 

nhưng Hadley khuyên nên sử dụng phương pháp setNames để thay thế.

+0

Vui lòng không sử dụng 'tên <-' nastiness -' setNames() 'là tốt hơn nhiều – hadley

+0

Tôi đã chỉnh sửa câu trả lời của mình để phản ánh điều đó. –

Các vấn đề liên quan