2013-01-02 34 views
6

Tôi có hai data.tables, DT và L:Nhiều gia nhập/hợp nhất với data.tables

> DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9,key="x") 
> L=data.table(yv=c(1L:8L,12L),lu=c(letters[8:1],letters[12]),key="yv") 

> DT 
    x y v 
1: a 1 1 
2: a 3 2 
3: a 6 3 
4: b 1 4 
5: b 3 5 
6: b 6 6 
7: c 1 7 
8: c 3 8 
9: c 6 9 

> L 
    yv lu 
1: 1 h 
2: 2 g 
3: 3 f 
4: 4 e 
5: 5 d 
6: 6 c 
7: 7 b 
8: 8 a 
9: 12 l 

Tôi muốn độc lập tìm kiếm các giá trị tương ứng của lu từ L cho cột y và cho cột v trong DT. Cú pháp sau đây cung cấp kết quả chính xác, nhưng là cồng kềnh để tạo ra và sau đó hiểu trong nháy mắt sau:

> L[setkey(L[setkey(DT,y)],v)][,list(x,y=yv.1,v=yv,lu.1=lu.1,lu.2=lu)] 
    x y v lu.1 lu.2 
1: a 1 1 h h 
2: a 2 3 g f 
3: a 3 6 f c 
4: b 4 1 e h 
5: b 5 3 d f 
6: b 6 6 c c 
7: c 7 1 b h 
8: c 8 3 a f 
9: c 9 6 NA c 

(Sửa: gốc bài đã L[setkey(L[setkey(DT,y)],v)][,list(x,y=yv,v=yv.1,lu.1=lu,lu.2=lu.1)] trên, mà sai lẫn lộn y và v cột và nhìn tăng giá trị)

Trong SQL này sẽ được đơn giản/dễ hiểu:.

SELECT DT.*, L1.lu AS lu1, L2.lu AS lu2 
FROM DT 
LEFT JOIN L AS L1 ON DT.y = L1.yv 
LEFT JOIN L AS L2 ON DT.v = L2.yv 

có cách thanh lịch hơn để sử dụng data.table để thực hiện nhiều tham gia? Lưu ý rằng tôi đang tham gia một bảng đến một bảng khác hai lần trong ví dụ này, nhưng tôi cũng quan tâm đến việc tham gia một bảng vào nhiều bảng khác nhau.

Trả lời

6

Câu hỏi hay. Một mẹo là i không cần phải được khóa. Chỉ có x phải được khóa.

Có thể có những cách tốt hơn. Làm thế nào về điều này:

> cbind(L[DT[,list(y)]], L[DT[,list(v)]], DT) 
    yv lu yv lu x y v 
1: 1 h 1 h a 1 1 
2: 3 f 2 g a 3 2 
3: 6 c 3 f a 6 3 
4: 1 h 4 e b 1 4 
5: 3 f 5 d b 3 5 
6: 6 c 6 c b 6 6 
7: 1 h 7 b c 1 7 
8: 3 f 8 a c 3 8 
9: 6 c 9 NA c 6 9 

hay, để minh họa, đây là giống nhau:

> cbind(L[J(DT$y)], L[J(DT$v)], DT) 
    yv lu yv lu x y v 
1: 1 h 1 h a 1 1 
2: 3 f 2 g a 3 2 
3: 6 c 3 f a 6 3 
4: 1 h 4 e b 1 4 
5: 3 f 5 d b 3 5 
6: 6 c 6 c b 6 6 
7: 1 h 7 b c 1 7 
8: 3 f 8 a c 3 8 
9: 6 c 9 NA c 6 9 

merge cũng có thể được sử dụng, nếu các yêu cầu tính năng sau đây được thực hiện:

FR#2033 Add by.x and by.y to merge.data.table

+0

Cảm ơn mẹo cbind và phản hồi nhanh. Phương pháp này ít được lồng và dễ đọc hơn so với lần thử ban đầu của tôi. Để làm sạch các tên cột kết quả, tôi sẽ sử dụng một cái gì đó như 'cbind (DT, L [J (DT $ y)] [, danh sách (lu.1 = lu)], L [J (DT $ v)]) [, danh sách (x, y, v, lu.1, lu.2 = lu)] '. Nền của tôi trong SQL đã điều chỉnh tôi để không bao giờ dựa vào thứ tự sắp xếp hàng, vì vậy việc kết hợp các cột cảm thấy sai, nhưng rõ ràng là nó hoạt động trong R. Tôi cần phải "suy nghĩ trong R" nhiều hơn. Người hâm mộ lớn về công việc của bạn, BTW. – dnlbrky

+0

Việc triển khai FR # 2033 có cho phép nhiều bảng được hợp nhất không? Như tôi đã hiểu, 'merge' được sử dụng cho hai khung dữ liệu, không nhiều. Tôi thấy một số tùy chọn như 'merge_all' và' merge_recurse' trong định dạng lại, nhưng tôi không thể tìm thấy quá nhiều ví dụ (đặc biệt là với một số khóa ngoại) vì vậy tôi không chắc chắn cách sử dụng chúng nếu chúng thậm chí làm việc trong thí dụ. – dnlbrky

+0

Nói chung trong R và trong data.table chúng tôi không sử dụng nhiều bảng. Các yếu tố tương tự như các phím nước ngoài trong sql, và những ngày này kể từ khi nhân vật được lưu trữ bởi R tự động trong bộ đệm ẩn toàn cầu của nó, nhân vật thực sự hiệu quả. Các bàn phẳng lớn, không chuẩn hóa, nói chung là tốt. Data.table chỉ nhóm các cột mà j cần để không có bất lợi của nhiều cột như có trong hàng (được lưu trữ) sql. –