读取固定宽度格式,其中宽度是从列标题中推断出来的
Posted
技术标签:
【中文标题】读取固定宽度格式,其中宽度是从列标题中推断出来的【英文标题】:Read fixed-width format, where the widths are inferred from the column headers 【发布时间】:2013-04-19 01:04:06 【问题描述】:我需要阅读一个相当奇怪的文件格式。它有以空格分隔的列,但列宽必须从标题中推断出来。
此外,还有一些虚假的行必须忽略,包括空白和非空白。
数据的表示:
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
包含从col1
中1
之后的下一个字符到文本字符串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
一定有更好的办法。
要忽略的行是这个难题的一小部分。我会接受一种适用于已从文件中删除的解决方案(但当然更喜欢不需要预处理的解决方案)。
【问题讨论】:
看起来像是sed
或 awk
在 R
之外的工作
@geektrader 要删除虚假的行,是的,但是推断列宽的更重要部分怎么样?
我认为你基本上有正确的方法。一次读取一行以到达标题行,解析它以获取作为字段边界的列号,然后使用这些边界调用read.fwf
。
【参考方案1】:
如果您知道标题行,则可以使用以下方法获取宽度。
x
## [1] " col1 col2 col3 col4 col5"
nchar(unlist(regmatches(x, gregexpr("\\s+\\S+", x))))
## [1] 13 9 5 5 10
【讨论】:
这可能比diff(c(0L, gregexpr('[^ ]( |$)', header)[[1]]))
更优雅,但我不能假设我知道标题行。我应该从文件中读取它。
@MatthewLundberg 您需要在要忽略的文本中有某种模式。在您的示例中,首先是 n
行,或者以 This
开头的行。
con
以上是关于读取固定宽度格式,其中宽度是从列标题中推断出来的的主要内容,如果未能解决你的问题,请参考以下文章
在 spark java 中读取具有固定宽度和分隔符的文本文件
R:如何读取固定宽度的数据文件,其中数据连接成两组,堆叠在一个文件的顶部