2014-02-17 43 views
0

我正在使用data.table對大數據集(45M行,4個int列)進行一些重複查找。如何使用data.table做多鍵查找?

這是我想要做的。

library(data.table) 
# generate some data, u's can show up in multiple s's 
d1 <- data.table(u=rep(1:500,2), s=round(runif(1000,1,100),0)) 
setkey(d1, u, s) 

# for each u, I want to lookup all their s's 
us <- d1[J(u=1), "s", with=F] 
# for each of the s's in the above data.table, 
# I want to lookup other u's from the parent data.table d1 

# DOESN'T WORK: 
otherus <- d1[J(s = us), "u", with=F] 

# THIS WORKS but takes a really long time on my large dataset: 
otherus <- merge(d1, us, by='s') 

合併適用於我的目的,但自從'd1'>>>'我們',它需要很長時間。起初我想也許我正在使用從基地合併,但基於文檔它看起來像data.table合併調度是類(first_arg合併)是一個data.table。

我仍然習慣data.table J()語法。有沒有更好的方法來完成這個?

在此先感謝。

+0

哎唷,這些名字很混亂。 「us」不應該指多個「u」,而不是多個'''與特定的'u'關聯?無論如何,這聽起來像是圖論。你在找鄰居吧?如果是這樣,你可能想看看'igraph'包。 – Frank

回答

1

您可以爲此更改密鑰。

setkey(d1,s,u) 

該命令後爲相同的值s所有u值分組在一起。

 u s 
    1: 20 1 
    2: 35 1 
    3: 36 1 
    4: 87 1 
    5: 123 1 
    ---   
996: 208 100 
997: 262 100 
998: 352 100 
999: 430 100 
1000: 455 100 

對由鍵列定義的組執行的操作通常非常快速,例如,

d1[,mean(u),keyby='s'] 

如果您需要爲這兩個羣體us做快速聚集,你可以存儲data.table的兩個實例。對於您使用setkey(d1,u,s)和其他setkey(d1,s,u)。如果你想快速在由u的值定義的組上執行操作,則使用前面的data.table,否則使用後者。

+0

謝謝@Georg。我實際上已經做到了 - 基本上有不同組合鍵的data.table的兩個副本。數據集很大,我需要在foreach循環中執行此操作,我相信這會爲每個「工作人員」創建一個副本,以便RAM快速填充。我希望有另一種解決方案。感謝您的期待。 – user3053307

+1

嗯,也許有可能僅存儲索引列''u'and加s'兩個data.tables行標識符保存存儲器並與'bigmemory'包,其允許存儲矩陣共享存儲器以某種方式結合它。 – Georg

0

請問以下工作?

d1 <- data.table(u=rep(1:500,2), s=round(runif(1000,1,100),0)) 
setkey(d1, u, s) 
us <- d1[J(u=1), "s", with=F] 
otherus <- merge(d1, us, by='s') 

setkey(d1,s) 
otherus2 <- d1[us] 
identical(otherus2, otherus) 

setkey(d1, u, s)