在R中加速字符串匹配的性能和速度

时间:2014-01-27 21:16:36

标签: string r performance

我遇到了需要帮助的性能问题。请耐心解释:

我有一个已知的Car Vin#和数年的数据库(只有前4行显示~~ 5,000):

>vinDB
>ToyotaCarola 2008
 IJDINJNDJIJKNDJIMKDK0897
 NissanAltima 1998
 LJIODJJNJDJNJDNJNJDJ7765

我还有一个.txt文档,它以下列方式显示一个唯一的DMV ID,一个vin号和一个参考号(为了方便起见,只显示了4行~5500万行):

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

我想要做的是从我的'vinDB'文件中每隔一行(VIN#)扫描我的'carFile'文件的每四行(从第二行开始)以获得完美匹配。如果匹配存在,我想输出汽车的名称,以及在“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)使上面的代码更快,更有效。

2)如何将输出存储在.txt或.csv文件中(因为现在,它只显示屏幕上的输出)。

谢谢!

1 个答案:

答案 0 :(得分: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内使用它。通过在data.table内使用dt,我们将vins列表添加到汽车列表中,因为我们在前一步骤中将dt键入“vin.vins”。最后一个参数告诉我们按vin.names对连接集进行分组,以及我们想知道每个组的.N实例数的中间参数(.N是一个特殊的{{1}变量)。

另外,我制作了一些垃圾数据来运行它。将来,请提供这样的数据。

data.table