2014-07-06 60 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