2017-02-11 1 views
2

У меня есть данные, подобные этим, за исключением dt1 имеет 29 миллионов строк и dt2 имеет только 15 строк (не 15 миллионов).Объединение двух data.tables, где все строки в dt2 объединены с каждой строкой в ​​dt1

dt1 <- data.table(ID=1:4,City=c("Charlotte","DC","Salem","Boston")) 
dt2 <- data.table(Birds=c("Saker","Peregrine","Barbary","Prarie","Golden","Coopers","Canary","Finch"),BirdType=c("Falcon","Falcon","Falcon","Falcon","Eagle","Hawk","Breakfast","Breakfast")) 

, который выводит так:

> dt1 
    ID  City 
1: 1 Charlotte 
2: 2  DC 
3: 3  Salem 
4: 4 Boston 

> dt2 
     Birds BirdType 
1:  Saker Falcon 
2: Peregrine Falcon 
3: Barbary Falcon 
4: Prarie Falcon 
5: Golden  Eagle 
6: Coopers  Hawk 
7: Canary Breakfast 
8:  Finch Breakfast 

Я хотел бы объединить два data.tables причем каждая строка dt1 сочетается со всеми рядами dt2, в конечном счете, давая data.table с 32 строки с выходом следующим образом:

> dtMerged 
    ID  City Birds  BirdType 
1: 1 Charlotte Saker  Falcon 
2: 1 Charlotte Peregrine Falcon 
3: 1 Charlotte Barbary Falcon 
4: 1 Charlotte Prarie  Falcon 
5: 1 Charlotte Golden  Eagle 
6: 1 Charlotte Coopers Hawk 
7: 1 Charlotte Canary Breakfast 
8: 1 Charlotte Finch Breakfast 
9: 2  DC Saker  Falcon 
10: 2  DC Peregrine Falcon 
11: 2  DC Barbary Falcon 
12: 2  DC Prarie  Falcon 
13: 2  DC Golden  Eagle 
14: 2  DC Coopers Hawk 
15: 2  DC Canary Breakfast 
16: 2  DC Finch Breakfast 
17: 3  Salem Saker  Falcon 
18: 3  Salem Saker  Falcon 
etc... 

Любые идеи о том, как наилучшим образом выполнить это, будут очень признательны. Я использую data.table версии 1.10.4 на ПК с Windows 7. Благодарю.

+2

Вы можете использовать 'CJ' для выполнения кросс-соединения, то есть' CJ (do.call (paste, c (dt1, sep = ",")), do.call (paste, c (dt2, sep = ","))) [, unlist (lapply (.SD, tstrsplit, split = ","), recursive = FALSE)] ' – akrun

+0

Спасибо @akrun. Крест-соединение - это путь. – FG7

+2

'dt1 [, as.list (dt2), by = names (dt1)]' также, похоже, работает. О, или, может быть, сделайте это наоборот, поскольку dt2 имеет так много меньше строк в вашем реальном случае использования. Кроме того, если каждое имя птицы уникально, вы можете сохранить эти две меньшие таблицы и просто создать новый, содержащий только Птицы и Идентификатор, несколько сохраняя память: 'CJ (ID = dt1 $ ID, BirdName = dt2 $ Birds)'. Тогда вы можете просто взглянуть на город с идентификатора и типа птицы от имени по мере необходимости. – Frank

ответ

1

Как прокомментировал @akrun, кросс-соединение, по-видимому, является одним из способов решения проблемы. Для того, чтобы осуществить это, я сослался на очень аккуратную функции @jangorecki CJ.dt в this Stack Overflow post, чтобы добраться до нужного решения:

CJ.dt = function(X,Y) { 
    stopifnot(is.data.table(X),is.data.table(Y)) 
    k = NULL 
    X = X[, c(k=1, .SD)] 
    setkey(X, k) 
    Y = Y[, c(k=1, .SD)] 
    setkey(Y, NULL) 
    X[Y, allow.cartesian=TRUE][, k := NULL][] 
} 

new_df <- CJ.dt(dt1, dt2) 
setorder(new_df, ID) 

Вот как выглядит полный выход, как, после повторного заказ:

> new_df 

ID  City  Birds BirdType 
1: 1 Charlotte  Saker Falcon 
2: 1 Charlotte Peregrine Falcon 
3: 1 Charlotte Barbary Falcon 
4: 1 Charlotte Prarie Falcon 
5: 1 Charlotte Golden  Eagle 
6: 1 Charlotte Coopers  Hawk 
7: 1 Charlotte Canary Breakfast 
8: 1 Charlotte  Finch Breakfast 
9: 2  DC  Saker Falcon 
10: 2  DC Peregrine Falcon 
11: 2  DC Barbary Falcon 
12: 2  DC Prarie Falcon 
13: 2  DC Golden  Eagle 
14: 2  DC Coopers  Hawk 
15: 2  DC Canary Breakfast 
16: 2  DC  Finch Breakfast 
17: 3  Salem  Saker Falcon 
18: 3  Salem Peregrine Falcon 
19: 3  Salem Barbary Falcon 
20: 3  Salem Prarie Falcon 
21: 3  Salem Golden  Eagle 
22: 3  Salem Coopers  Hawk 
23: 3  Salem Canary Breakfast 
24: 3  Salem  Finch Breakfast 
25: 4 Boston  Saker Falcon 
26: 4 Boston Peregrine Falcon 
27: 4 Boston Barbary Falcon 
28: 4 Boston Prarie Falcon 
29: 4 Boston Golden  Eagle 
30: 4 Boston Coopers  Hawk 
31: 4 Boston Canary Breakfast 
32: 4 Boston  Finch Breakfast 
+0

Большое спасибо @ david-c. Это работало отлично и быстро на моем большом наборе данных. – FG7

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