R中for循环的更快替代,它用另一个循环调用一个函数

时间:2014-07-06 19:01:57

标签: r performance parsing for-loop foreach

我正在尝试将一个庞大的数据集解析为R(1.3Gb)。原始数据是由四百万个字符组成的列表,其中每个字符都是137个变量的观察值。

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

“2005400d”

,密钥将是

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

其中varIn和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库,但它没有像我预期的那样使用并行。

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

1 个答案:

答案 0 :(得分:3)

为什么重新发明轮子?在utils包中使用read.fwf(默认附加)

> 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

如果指定colClasses,您应该获得更高的效率,但我努力证明这一点未能显示出差异。也许这个建议只适用于read.table和堂兄弟。