【问题标题】:Reading large fixed format text file in r在r中读取大型固定格式文本文件
【发布时间】:2014-03-09 21:39:32
【问题描述】:

我正在尝试将一个大 (> 70 MB) 的固定格式文本文件输入到 r。对于较小的文件(

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

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

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

我收到以下错误消息:

错误:无法分配大小为 2 Kb 的向量

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

我要导入的文件的格式在名为 testcsv3 的数据框中给出。我在下面展示了一个小数据框的 sn-p:

> 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)

我收到以下错误消息:

read.table 中的错误(impfile1, sep = testcsv3$Varsep, col.names = testcsv3$Varname, : 'sep' 参数无效

最后,我尝试使用:

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 格式以及每个变量开始的列。

谢谢,

沃伦

【问题讨论】:

  • 看看ff package。或者也许值得创建一个数据库并使用 RODBC 访问数据
  • 看看 mnel 在here 中的回答(最新)

标签: r text


【解决方案1】:

也许这段代码对你有用。您必须使用字段大小填充 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)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 2016-04-26
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多