Чтение файла формата фиксированной ширины в R

Я пытаюсь прочитать этот файл фиксированной ширины в R с помощью read.fwf:

http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for

Когда я выполняю эту функцию, я получаю некоторые странные ошибки, с которыми я не могу разобраться, если не прочитаю их очень конкретным образом:

> fwf <- read.fwf("getdata_wksst8110.for", 1:9, skip = 4)
> head(fwf)
  V1 V2  V3   V4 V5     V6  V7       V8   V9
1 NA  3 JAN 1990 NA 23.4-0 0.4 25.1-0.3 26.6
2 NA 10 JAN 1990 NA 23.4-0 0.8 25.2-0.3 26.6
3 NA 17 JAN 1990 NA 24.2-0 0.3 25.3-0.3 26.5
4 NA 24 JAN 1990 NA 24.4-0 0.5 25.5-0.4 26.5
5 NA 31 JAN 1990 NA 25.1-0 0.2 25.8-0.2 26.7
6 NA  7 FEB 1990 NA 25.8 0 0.2 26.1-0.1 26.8

Однако вы ясно видите, что, сравнивая вывод с исходным файлом, это неправильно. Действительно, должно быть 9 столбцов, но это сокращает мои столбцы даты и другие столбцы.

Если я использую аргумент sep = "", он просто выдаст ошибку:

> fwf <- read.fwf("getdata_wksst8110.for", 1:9, skip = 4, sep = " ")
Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  : 
  line 6 did not have 25 elements

Не мог бы кто-нибудь, пожалуйста, помочь мне понять, почему это не читается так, как я ожидал?

Я нашел эту полезную ссылку, связанную с использованием этой функции, но это скорее вопрос, связанный с производительностью. Автор никогда не определял свои аргументы width = col.

Спасибо за рассмотрение этого крошечного вопроса.

Поэтому я повторно выполнил операцию, используя вектор ширины, как рекомендовано @MrFlick, и данные выглядят намного лучше. Однако я вижу, что аргумент "сеп" явно несет хаос. Если я использую sep = "", возникает странная ошибка. Но если я не использую sep, мои результаты в столбце резко ухудшаются.

*

Non-jerked results using widths = c(10, 4, 4, 4, 4, 4, 4, 4, 4)
    > head(fwf)
              V1 V2 V3   V4 V5 V6   V7  V8 V9
    1  03JAN1990 NA 23 4-0.  4 25 .1-0 0.3  2
    2  10JAN1990 NA 23 4-0.  8 25 .2-0 0.3  2
    3  17JAN1990 NA 24 2-0.  3 25 .3-0 0.3  2
    4  24JAN1990 NA 24 4-0.  5 25 .5-0 0.4  2
    5  31JAN1990 NA 25 1-0.  2 25 .8-0 0.2  2
    6  07FEB1990 NA 25 8 0.  2 26 .1-0 0.1  2

Подергивание результатов с использованием:

fwf ‹- read.fwf (" getdata_wksst8110.for ", widths = c (10, 4, 4, 4, 4, 4, 4, 4, 4), skip = 4, sep =" ") Ошибка при сканировании (файл , what, nmax, sep, dec, quote, skip, nlines, na.strings,: в строке 6 не было 25 элементов

Я что-то упускаю с sep?

#

Модификация классного скрипта @ MrFlick, похоже, отвечает всем требованиям (более или менее)! Эта первая строка оставалась проблемной и не позволяла мне подвести итоги на HD [4]. Удаление первой строки hd [-1,], как ни странно, не помогло. Ну что ж.

hd<-read.fwf("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for", 
             widths=c(10,rep(c(9,4),4)), skip=3)

trim <- function(x) gsub("^\\s+|\\s+$","",x)
main <- paste0(trim(hd[1,seq(2, ncol(hd), by=2)]), trim(hd[1,seq(3, ncol(hd), by=2)]))
sub <- trim(as.vector(hd[2,]))

names(hd) <- make.names(c(sub[1],paste(rep(main, each=2), sub[-1])))

person Zach    schedule 06.05.2015    source источник
comment
Как вы думаете, что делает 1:9? Этот параметр должен указывать ширину каждого столбца (с точки зрения количества символов). Не похоже, что вы правильно указали ширину столбцов. Также вы можете посмотреть на функцию read_fwf из readr, потому что базовая функция read.fwf довольно неэффективна (если это должно вызывать беспокойство).   -  person MrFlick    schedule 06.05.2015
comment
Я читаю документацию и читаю таблицу. Ширина столбцов является переменной для всех столбцов. Например, дата 9L, а остальные 8 столбцов обычно варьируются от 3 до 4L. -0,50 = 4, 25,5 = 3, 0,03 = 3 и т. Д.   -  person Zach    schedule 06.05.2015
comment
Вот почему вы указываете вектор ширины. Итак, если первый - 8 символов, а второй - 4, то вы начинаете с c(8, 4, ...). Вы указываете ширину для каждого из 9 столбцов.   -  person MrFlick    schedule 06.05.2015
comment
‹Лицо ладонью› Я все время забываю, что вы можете предоставить вектор точек данных, которые будут использоваться.   -  person Zach    schedule 06.05.2015
comment
Установка widths = 4 означает, что у вас есть только один столбец шириной 4. Если у вас 9 столбцов шириной 4, вы должны сделать widths=c(4,4,4,4,4,4,4,4,4) или, более кратко, widths=rep(4,9). Это то, что касается файлов фиксированной ширины, вам нужно указать всю ширину всех столбцов; это единственный способ узнать, как разобрать файл.   -  person MrFlick    schedule 06.05.2015


Ответы (1)


Вот команда, которая должна считывать данные

dd<-read.fwf("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for",
    widths=c(10, rep(c(9,4),4)), skip=4)

Обратите внимание, что ширина должна учитывать все символы в каждой строке, поэтому даже если между столбцами есть пробелы, вам необходимо назначить их одному из столбцов.

Тогда я не могу придумать сверхчистый способ получить заголовки. Это работает, но это некрасиво и делает предположения

hd<-read.fwf("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for", 
    widths=c(10,rep(c(9,4),4)), skip=2, nrow=2, as.is=T)

trim <- function(x) gsub("^\\s+|\\s+$","",x)
main <- paste0(trim(hd[1,seq(2, ncol(hd), by=2)]), trim(hd[1,seq(3, ncol(hd), by=2)]))
sub <- trim(as.vector(hd[2,]))

names(dd) <- make.names(c(sub[1],paste(rep(main, each=2), sub[-1])))

и, наконец, вы можете установить правильное значение даты с помощью

dd$Week <- as.Date(as.character(dd$Week), "%d%b%Y")

Вам вообще не следует использовать параметр sep=. На самом деле read.fwf переписывает фиксированный файл с помощью файла с разделителями, используя sep в качестве разделителя, а затем читает файл с разделителями с более стандартным read.table(). Значение по умолчанию sep="\t" обычно безопасно, так как обычно у вас нет вкладок в ваших фактических данных.

person MrFlick    schedule 06.05.2015