2013-04-19 2 views
1

У меня есть довольно странный формат файла, который мне нужно прочитать. Он имеет столбцы, разделенные пробелами, но ширина столбцов должна быть выведена из заголовка.Прочитайте формат фиксированной ширины, где ширины выводятся из заголовков столбцов

Кроме того, есть некоторые фиктивные строки, которые необходимо игнорировать, как пустые, так и незаполненные.

Представление данных:

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 содержит текст следующего символа после 1 в col1 до конца текстовой строки 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 
} 

Там должно быть лучше.

Линии, которые следует игнорировать, являются небольшим фрагментом этой головоломки. Я приму решение, которое работает с уже удаленными из файла (но, конечно, предпочтет тот, который не нуждается в предварительной обработке).

+0

выглядит как работа для 'sed' или' 'awk' вне r' –

+0

@geektrader Для удаления фиктивных линий, да, но как насчет более важной части выводя ширину столбцов? –

+0

Я думаю, вы в принципе имеете правильный подход. Прочитайте строку за раз, чтобы добраться до строки заголовка, проанализировать, что это было так, чтобы получить номера столбцов, которые являются границами полей, а затем вызывать 'read.fwf', используя эти границы. –

ответ

-1

Если вы знаете свою строку заголовка, вы можете получить ширину, используя следующий метод.

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

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

Это может быть более элегантно, чем 'diff (c (0L, gregexpr ('[^] (| $)', header) [[1]]))', но я не могу предположить, что знаю строку заголовка. Я должен прочитать его из файла. –

+0

@MatthewLundberg Вам нужно иметь какой-то шаблон в тексте, который вы хотите игнорировать. Либо, сначала 'n', либо строки, начинающиеся с' This' в вашем примере. –

+0

Я отредактирую вопрос, чтобы сделать его более понятным. –