2015-01-24 11 views
12

Come unire 2 tabelle utilizzando * _join() da dplyr, quando i nomi delle variabili di join sono diversi e memorizzati in un'altra variabile?R: valutazione standard per * _join (dplyr)

ad es.

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 

ma questo dà l'errore -

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

sorprendentemente, questo funziona -

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

risposta

17

Il problema qui è che avete per la fornitura di un vettore di nome se la colonna comune ha nomi diversi nei dataframes. Vedere cosa succede nel tuo esempio:

Funziona quando si fornisce i nomi direttamente:

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 

E il nome vettore fornite è:

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

Ora, se si utilizzano vettori di caratteri, il named vector cambia in:

var1 = "x1" 
var2 = "x2" 

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

Non so se c'è un modo "pulito" per risolvere questo in dply al momento Una soluzione è la seguente tweak per costruire il vettore nominato come richiesto:

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 

Questo funziona perché:

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

Speranza che aiuta.


Nota: si potrebbe fare lo stesso con names<- in questo modo:

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

ma Hadley consiglia di utilizzare l'approccio setNames invece.

+0

Si prega di non utilizzare il 'nome <-' nastiness -' setNames() 'è molto meglio – hadley

+0

Ho modificato la mia risposta per riflettere questo. –

Problemi correlati