2014-07-06 59 views
0

我想解析一个巨大的数据集到R(1.3Gb)。原始数据是由四百万个字符组成的列表,其中每一个都是对137个变量的观察。更快的替代R for循环调用另一个循环的函数

首先,我创建了一个函数,根据数据集中提供的关键字分隔字符,其中“d”是每个字符之一。对于这个问题的目的想象d具有这种形式

“2005400d”

,关键是

varName <- c("YEAR","AGE","GENDER","STATUS") 
varIn <- c(1,5,7,8) 
varEND <- c(4,6,7,8) 

其中瓦兰和varEnd跟踪分割点。创建的功能是。

parseLine<-function(d){ 
    k<-unlist(strsplit(d,"")) 
    vec<-rep(NA,length(varName)) 
    for (i in 1:length(varName)){ 
    vec[i]<-paste(k[varIn[i]:varEnd[i]],sep="",collapse="") 
    } 
    return(vec) 
} 

然后为了遍历所有可用的数据,我创建了一个for循环。

df<-data.frame(matrix(ncol=length(varName))) 
names(df)<-as.character(varName) 

for (i in 1:length(data)){ 
    df<-rbind(df,parseLine(data[i])) 
} 

然而,当我检查功能与1000次迭代我得到了10.82秒的系统时间,但是当我增加的10,000而不是108.2秒的时间,我得到了614.77时间指示随着迭代次数的增加,所需时间将呈指数增长。

有关加快流程的任何建议?我试过使用库foreach,但并没有像我期望的那样使用parallel。

m<-foreach(i=1:10,.combine=rbind) %dopar% parseLine(data[i]) 
df<-a 
names(df)<-as.character(varName) 
+1

在你的第一个循环中,你是否正在做'substring(“2005400d”,varIn,varEND)'?如果没有,看起来你可以使用类似的东西(这也更快) –

+2

你的原始数据格式是固定的宽度吗?然后[**这篇文章**](http://stackoverflow.com/questions/18720036/reading-big-data-with-fixed-width)可能是相关的。 – Henrik

+1

不保留对数据帧的'绑定';创建一个单独的数据框架列表,然后'do.call(rbind,ListOfDataFrames)' –

回答

3

为什么重新发明轮子?如果指定colClasses但我的努力证明这并没有表现出差异使用read.fwf在utils软件包(默认情况下附后)

> dat <- "2005400d" 
> varName <- c("YEAR","AGE","GENDER","STATUS") 
> varIn <- c(1,5,7,8) 
> varEND <- c(4,6,7,8) 
> read.fwf(textConnection(dat), col.names=varName, widths=1+varEND-varIn) 
    YEAR AGE GENDER STATUS 
1 2005 40  0  d 

你应该得到进一步提高效率。也许这个建议只适用于read.table和堂兄弟。

+0

我很愚蠢......非常感谢你我不知道read.fwf函数......非常感谢! – comendeiro