2014-01-27 41 views
0

我有一個性能問題,我需要幫助。請和我一起承擔的解釋:加速字符串匹配的性能和速度R

我(爲便於只顯示前4行〜5000)的知名汽車Vin的#和多年的數據庫:

>vinDB 
>ToyotaCarola 2008 
IJDINJNDJIJKNDJIMKDK0897 
NissanAltima 1998 
LJIODJJNJDJNJDNJNJDJ7765 

我也有AA的.txt文件這顯示出獨特的DMV ID,一個VIN號碼,並通過以下方式參考號(僅4行〜55所示億便於):

>carFile 
>#DMVcorrNumber33:1245638:563892:6378 
IJDINJNDJIJKNDJIMKDK0897 
+ 
VIN#IDref6388546 
#DMVcorrNumber33:1245638:563892:6378 
LJIODJJNJDJNJDNJNJDJ7765 
+ 
VIN#IDref2453663 

我希望做的是掃描每個二線(VIN#)從我的'carFile'文件的每第四行(從第二行開始)從我的'vinDB'文件樂一場完美的比賽。如果匹配存在,我想輸出車的名字,以及在'carFile'文件中看到多少次。

因此,基本上,我需要這樣的:

Car   Year  NumTimesFound 
ToyotaCarola  2008   238 
NissanAltima  1998   1755 

到目前爲止,我有以下的代碼,它的工作原理上截斷「carFile」文件,但崩潰我的[R計劃時,我嘗試將所有〜5500萬行:

VinCounter<-function(carFile, vinDB) 

{ 
i=1 #index inner while loop 
j=1 #index outer while loop 
m=2 #index of vinDB, starts at '2' because first VIN# is on line 2 
s=2 #index of carFile 
count=0 

while(j<=length(rownames(vinDB))/2) # VIN# is on every 2nd line in vinDB file 
{ 
    while(i<=length(rownames(carFile))/4)# VIN# is on every 4th line in carFile file 
    { 
    if(vinDB[m,1]==carFile[s,1]) 
     { 
     count=count+1 
     s=s+4 
     } 
    else 
     { 
     s=s+4 
     } 
    i=i+1 
    } 
print(vinDB[m-1,1]) 
print(count) 
count=0 
s=2 
i=1 
m=m+2 
j=j+1 
} 

} 

所以,基本上,我想弄清楚如何:

1)使上面的代碼quicked,更高效。

2)如何將我的輸出存儲在.txt或.csv文件中(因爲現在它只顯示屏幕上的輸出)。

謝謝!

回答

4

你可以用data.table做到這一點相對容易:

vin.names <- vinDB[seq(1, nrow(vinDB), 2), ] 
vin.vins <- vinDB[seq(2, nrow(vinDB), 2), ] 
car.vins <- carFile[seq(2, nrow(carFile), 4), ] 

library(data.table) 
dt <- data.table(vin.names, vin.vins, key="vin.vins") 
dt[J(car.vins), list(NumTimesFound=.N), by=vin.names] 
#   vin.names NumTimesFound 
# 1:  Ford 2014   15 
# 2: Chrysler 1998   10 
# 3:  GM 1998    9 
# 4:  Ford 1998   11 
# 5: Toyota 2000   12 
# ---        
# 75: Toyota 2007    7 
# 76: Chrysler 1995    4 
# 77: Toyota 2010    5 
# 78: Toyota 2008    1 
# 79:  GM 1997    5  

最主要的瞭解與J(car.vins)我們正在創建一個列data.table與VINS匹配(J只是簡寫data.table,只要因爲您在data.table內使用它)。通過在dt內部使用data.table,我們將vins列表加入汽車列表,因爲我們在上一步中通過「vin.vins」鍵入了dt。最後一個參數告訴我們將vin.names加入的集合以及我們想要知道每個組的實例數.N的中間參數(.N是特殊的data.table變量)。

另外,我做了一些垃圾數據來運行它。未來,請提供這樣的數據。

set.seed(1) 
makes <- c("Toyota", "Ford", "GM", "Chrysler") 
years <- 1995:2014 
cars <- paste(sample(makes, 500, rep=T), sample(years, 500, rep=T)) 
vins <- unlist(replicate(500, paste0(sample(LETTERS, 16), collapse=""))) 
vinDB <- data.frame(c(cars, vins)[order(rep(1:500, 2))])    
carFile <- 
    data.frame(
    c(rep("junk", 1000), sample(vins, 1000, rep=T), rep("junk", 2000))[order(rep(1:1000, 4))] 
) 
+0

非常感謝!我需要一勞永逸地學習'data.table'的力量。再次感謝! –