读取固定宽度格式,其中宽度是从列标题推断出来的

时间:2013-04-19 01:04:07

标签: r dataframe read.table

我有一个相当奇怪的文件格式,我需要阅读。它具有以空格分隔的列,但必须从标题中推断出列宽。

此外,还有一些虚假的行必须被忽略,包括空白和非空白。

数据的表示:

The first line contains some text that is not important, and shoud be ignored.
The second line also.  In addition, the third and fifth lines are blank.

       col1          col2    col3  col4     col5

  ab   cd e      132399.4     101     0 17:25:24  Ignore anything past the last named column
       blah        773411      25    10 17:25:25  Ignore this too

此处,第一列col1包含从行开头到文本字符串col1结尾的字符位置的文本。第二列col2包含1col1之后的下一个字符的文字,直到文字字符串col2的结尾。等等。

实际上,有17列而不是5列,但这不应该改变代码。

我正在寻找包含内容的数据框:

         col1     col2 col3 col4      col5
1   ab   cd e 132399.4  101    0  17:25:24
2        blah 773411.0   25   10  17:25:25

这是一种相当不优雅的方法:

read.tt <- function(file) {
  con <- base::file(file, 'r')
  readLines(con, n=3);
  header <- readLines(con, n=1)
  close(con)
  endpoints <- c(0L, gregexpr('[^ ]( |$)', header)[[1]])
  widths <- diff(endpoints)
  names <- sapply(seq_along(widths),
                  function(i) substr(header, endpoints[i]+1, endpoints[i]+widths[i]))
  names <- sub('^ *', '', names)
  body <- read.fwf(file, widths, skip=5)
  names(body) <- names
  body
}

必须有更好的方法。

要忽略的线条是这个难题的一小部分。我将接受一个解决方案,该解决方案适用于已从文件中删除的解决方案(但当然更喜欢不需要预处理的解决方案)。

1 个答案:

答案 0 :(得分:0)

如果您知道标题行,则可以使用以下方法获取宽度。

x
## [1] "         col1     col2 col3 col4      col5"

nchar(unlist(regmatches(x, gregexpr("\\s+\\S+", x))))
## [1] 13  9  5  5 10