我遇到了需要帮助的性能问题。请耐心解释:
我有一个已知的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文件中(因为现在,它只显示屏幕上的输出)。
谢谢!
答案 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