2013-12-16 2 views
1

У меня есть два кадра данных, который выглядит следующим образом:Как присоединиться data.frames на основе двух столбцов

d1 <- data.frame(h1 = c("foo","foo","bar","bar"), h2= c("a","b","c","d"), h3=c("x1","x2","x3","x4")) 

который печатает:

h1 h2 h3 
1 foo a x1 
2 foo b x2 
3 bar c x3 
4 bar d x4 

И

d2 <- data.frame(t1= c("a","b","c","d"), t2=c("x1","x2","x3","x4"),val=(rnorm(4))) 

который производит :

t1 t2  val 
1 a x1 -1.183606 
2 b x2 -1.358457 
3 c x3 -1.512671 
4 d x4 -1.253105 
# surely the val columns will differ since we use rnorm() 

То, что я хочу сделать, это объединить Д1 и Д2 на основе h2-h3 в d1 и t1-t2 столбца в d2, в результате

foo a x1 -1.183606 
foo b x2 -1.358457 
bar c x3 -1.512671 
bar d x4 -1.253105 

Что способ сделать это?

ответ

2

Объединить работает с несколькими ключами, и может использовать разные имена столбцов для каждой стороны. Для by спецификации, x является первым кадром данных, y является вторым:

merge(d1, d2, by.x=c('h2', 'h3'), by.y=c('t1', 't2')) 
## h2 h3 h1   val 
## 1 a x1 foo -0.04356036 
## 2 b x2 foo 0.56975774 
## 3 c x3 bar 0.03251157 
## 4 d x4 bar -0.67823770 
1

Я думаю, что это следует сделать трюк - создать один ключ из пары столбцов для каждого кадра данных, а затем объединить на этой клавише:

d1$key = paste(d1$h2, d1$h3) 
d2$key = paste(d2$t1, d2$t2) 
merged = merge(d1, d2) 
1

Вот еще один подход с использованием data tables.

Соединения исключительно эффективны с таблицами данных. Даже с этими крошечными наборами данных соединение с таблицей данных примерно в два раза быстрее, хотя вы этого не заметите. С большими наборами данных разница огромна.

# data frames with 200,000 rows, same structure as OP's example 
df1 <- data.frame(h1=rep(c("foo","foo","bar","bar"),each=50000), 
        h2=rep(letters[1:20],1e4), 
        h3=rep(1:1e4,each=20)) 
df2 <- data.frame(t1=rep(letters[1:20],1e4), 
        t2=rep(1:1e4,each=20), 
        val=rnorm(2e5)) 
# time the merge (~8.4 sec) 
system.time(df.result <-merge(df1, df2, by.x=c('h2', 'h3'), by.y=c('t1', 't2'))) 
# user system elapsed 
# 8.41 0.02 8.42 

# convert to data tables and set keys 
library(data.table) 
dt1 <- data.table(df1, key="h2,h3") 
dt2 <- data.table(df2, key="t1,t2") 
# time the join (~0.2 sec) 
system.time(dt.result <- dt1[dt2]) 
# user system elapsed 
# 0.19 0.00 0.18 

Нижняя линия: соединения таблиц данных в 40 раз быстрее на больших наборах данных.

Смежные вопросы