【问题标题】:Accelerate performance and speed of string match in R加快 R 中字符串匹配的性能和速度
【发布时间】:2014-01-27 21:16:36
【问题描述】:

我有一个性能问题需要帮助。请多多包涵:

我有一个已知汽车 Vin# 和年份的数据库(为方便起见,仅显示 ~5,000 的前 4 行):

>vinDB
>ToyotaCarola 2008
 IJDINJNDJIJKNDJIMKDK0897
 NissanAltima 1998
 LJIODJJNJDJNJDNJNJDJ7765

我还有一个 .txt 文档,其中显示了唯一的 DMV ID、VIN 号和参考号,方式如下(为方便起见,仅显示了约 5500 万行的 4 行):

>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 文件中(因为现在,它只是在屏幕上显示输出)。

谢谢!

【问题讨论】:

    标签: string r performance


    【解决方案1】:

    您可以使用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))]
      )  
    

    【讨论】:

    • 非常感谢!我需要一劳永逸地学习“data.table”的力量。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 2014-09-21
    • 2015-06-22
    相关资源
    最近更新 更多