2014-02-11 82 views
0

我正在尝试将大型(> 70 MB)固定格式文本文件输入到r中。对于较小的文件(< 1MB),我可以使用read.fwf()函数,如下所示。读取r中的大型固定格式文本文件

condodattest1a <- read.fwf(impfile1,widths=testcsv3$Varlen,col.names=testcsv3$Varname) 

当我尝试运行的下面的代码行,

condodattest1 <- read.fwf(impfile,widths=testcsv3$Varlen,col.names=testcsv3$Varname) 

我得到以下错误消息:

Error: cannot allocate vector of size 2 Kb

的2行之间的唯一区别是大小输入文件。

我想要导入的文件的格式在名为testcsv3的数据框中给出。我下面展示的数据帧的一个小片段:

> head(testcsv3) 

    Varlen  Varname Varclass Varsep Varforfmt 
1  2   "V1" "character"  2 "A2.0" 
2  15   "V2" "character"  17 "A15.0" 
3  28   "V3" "character"  45 "A28.0" 
4  3   "V4" "character"  48 "F3.0" 
5  1   "V5" "character"  49 "A1.0" 
6  3   "V6" "character"  52 "A3.0" 

我的问题的至少一部分是我在所有的数据,当我使用read.fwf(因素正在读),我最终超过了内存限制在我的电脑上。

我试图使用read.table()作为格式化每个变量的一种方式,但似乎我需要使用该函数的文本分隔符。在下面的链接3.3节中有一个建议,我可以使用sep来标识每个变量开始的列。

http://data.princeton.edu/R/readingData.html

然而,当我使用下面的命令:

condodattest1b <- read.table(impfile1,sep=testcsv3$Varsep,col.names=testcsv3$Varname, colClasses=testcsv3$Varclass) 

我收到以下错误信息:

Error in read.table(impfile1, sep = testcsv3$Varsep, col.names = testcsv3$Varname, : invalid 'sep' argument

最后,我试图用:

condodattest1c <- read.fortran(impfile1,lengths=testcsv3$Varlen, format=testcsv3$Varforfmt, col.names=testcsv3$Varname) 

,但我得到了以下信息:

Error in processFormat(format) : missing lengths for some fields 
In addition: Warning messages: 
1: In processFormat(format) : NAs introduced by coercion 
2: In processFormat(format) : NAs introduced by coercion 
3: In processFormat(format) : NAs introduced by coercion 

所有我想在这一点上做的是格式化数据,当他们进入R作为比因素以外的东西。我希望这会限制我使用的内存量,并允许我实际输入文件。我将不胜感激关于我如何做到这一点的任何建议。我知道所有变量的Fortran格式和每个变量开始的列。

谢谢

沃伦

+0

看看到[FF包(HTTP://cran.r-project .ORG /网络/包/ FF/index.html的)。或者,也许这是值得创建一个数据库和访问RODBC的数据 – Barranka

+0

看看mnel的答案(最近)在[这里](http://stackoverflow.com/questions/1727772/quickly-reading-very-large-表-AS-dataframes-在-R) –

回答

0

也许这个代码对你的作品。你必须填写varlen与现场尺寸并添加相应类型的字符串(例如,数字,字符,整数)到colclasses

my.readfwf <- function(filename,varlen,colclasses) { 
    sidx <- cumsum(c(1,varlen[1:(length(varlen)-1)])) 
    eidx <- sidx+varlen-1 
    filecontent <- scan(filename,character(0),sep="\n") 
    if (any(diff(nchar(filecontent))!=0)) 
    stop("line lengths differ!") 
    nlines <- length(filecontent) 
    res <- list() 
    for (i in seq_along(varlen)) { 
    res[[i]] <- sapply(filecontent,substring,first=sidx[i],last=eidx[i]) 
    mode(res[[i]]) <- colclasses[i] 
    } 
    attributes(res) <- list(names=paste("V",seq_along(res),sep=""),row.names=seq_along(res[[1]]),class="data.frame") 
    return(res) 
}