Я пытаюсь загрузить этот некрасиво отформатированный набор данных в свой сеанс R: http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for
Weekly SST data starts week centered on 3Jan1990
Nino1+2 Nino3 Nino34 Nino4
Week SST SSTA SST SSTA SST SSTA SST SSTA
03JAN1990 23.4-0.4 25.1-0.3 26.6 0.0 28.6 0.3
10JAN1990 23.4-0.8 25.2-0.3 26.6 0.1 28.6 0.3
17JAN1990 24.2-0.3 25.3-0.3 26.5-0.1 28.6 0.3
Пока я могу читать строки с
x = readLines(path)
Но файл смешивает «пробелы» с «-» в качестве разделителей, и я не эксперт по регулярным выражениям. Я ценю любую помощь по превращению этого в красивый и чистый фрейм данных R. благодаря!
r
fixed-width
Фернандо
источник
источник
read.fwf
чтобы прочитать данные в формате фиксированной ширины.Ответы:
Это файл фиксированной ширины. Используйте,
read.fwf()
чтобы прочитать:x <- read.fwf( file=url("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for"), skip=4, widths=c(12, 7, 4, 9, 4, 9, 4, 9, 4)) head(x) V1 V2 V3 V4 V5 V6 V7 V8 V9 1 03JAN1990 23.4 -0.4 25.1 -0.3 26.6 0.0 28.6 0.3 2 10JAN1990 23.4 -0.8 25.2 -0.3 26.6 0.1 28.6 0.3 3 17JAN1990 24.2 -0.3 25.3 -0.3 26.5 -0.1 28.6 0.3 4 24JAN1990 24.4 -0.5 25.5 -0.4 26.5 -0.1 28.4 0.2 5 31JAN1990 25.1 -0.2 25.8 -0.2 26.7 0.1 28.4 0.2 6 07FEB1990 25.8 0.2 26.1 -0.1 26.8 0.1 28.4 0.3
Обновить
Пакет
readr
(выпущен в апреле 2015 г.) предоставляет простую и быструю альтернативу.library(readr) x <- read_fwf( file="http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for", skip=4, fwf_widths(c(12, 7, 4, 9, 4, 9, 4, 9, 4)))
Сравнение скорости:
readr::read_fwf()
было примерно в 2 раза быстрее, чемutils::read.fwf ()
.источник
readr::fwf_empty
угадать ширину для вас. В примерахreadr::read_fwf
показано использованиеreadr::fwf_empty
.Другой способ определения ширины ...
df <- read.fwf( file=url("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for"), widths=c(-1, 9, -5, 4, 4, -5, 4, 4, -5, 4, 4, -5, 4, 4), skip=4 )
-1 в аргументе ширины говорит о том, что есть односимвольный столбец, который следует игнорировать, -5 в аргументе ширины говорит, что есть пятисимвольный столбец, который также следует игнорировать ...
ссылка: https://www.inkling.com/read/r-cookbook-paul-teetor-1st/chapter-4/recipe-4-6
источник
Во-первых, этот вопрос взят непосредственно из курса Ликса Coursera «Получить данные и очистить их». Хотя есть еще одна часть вопроса, самая сложная часть - это чтение файла.
Тем не менее, курс в основном предназначен для обучения.
Я ненавижу процедуру фиксированной ширины в R. Это медленно, и для большого количества переменных очень быстро становится затруднительно игнорировать определенные столбцы и т. Д.
Я думаю, что его проще использовать,
readLines()
а затем из этого использоватьsubstr()
ваши переменныеx <- readLines(con=url("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for")) # Skip 4 lines x <- x[-(1:4)] mydata <- data.frame(var1 = substr(x, 1, 10), var2 = substr(x, 16, 19), var3 = substr(x, 20, 23), var4 = substr(x, 29, 32) # and so on and so on )
источник
mydata <- data.frame(var4 = substr(x,29,32))
если бы вам нужен только четвертый столбец данных. Кроме того, для пользователей Windows Notepad ++ с подключаемым модулем TextFX предоставит вам простую и понятную линейку с подсчетом символов, чтобы вы могли понять, что вводить в начальное и конечное значенияsubstr
. Однако обратите внимание, что значение остановки на единицу больше, чем позиция последнего символа, который вы хотите сохранить.Теперь вы можете использовать эту
read_fwf()
функцию вreadr
пакете Hadley Wickham .Следует ожидать огромного улучшения производительности по сравнению с базовой
read.fwf()
.источник
Я документирую здесь список альтернатив для чтения файлов фиксированной ширины в R, а также предоставляю некоторые тесты, которые являются самыми быстрыми.
Я предпочитаю комбинировать
fread
сstringi
; он конкурентоспособен как самый быстрый подход и имеет дополнительное преимущество (IMO) хранения ваших данных в видеdata.table
:library(data.table) library(stringi) col_ends <- list(beg = c(1, 10, 15, 19, 23, 28, 32, 36, 41, 45, 49, 54, 58), end = c(9, 14, 18, 22, 27, 31, 35, 40, 44, 48, 53, 57, 61)) data = fread( "http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for", header = FALSE, skip = 4L, sep = NULL )[, lapply(1:(length(col_ends$beg)), function(ii) stri_sub(V1, col_ends$beg[ii], col_ends$end[ii])) ][ , paste0("V", c(2, 5, 8, 11)) := NULL] # V1 V3 V4 V6 V7 V9 V10 V12 V13 # 1: 03JAN1990 23.4 -0.4 25.1 -0.3 26.6 0.0 28.6 0.3 # 2: 10JAN1990 23.4 -0.8 25.2 -0.3 26.6 0.1 28.6 0.3 # 3: 17JAN1990 24.2 -0.3 25.3 -0.3 26.5 -0.1 28.6 0.3 # 4: 24JAN1990 24.4 -0.5 25.5 -0.4 26.5 -0.1 28.4 0.2 # 5: 31JAN1990 25.1 -0.2 25.8 -0.2 26.7 0.1 28.4 0.2 # --- # 1365: 24FEB2016 27.1 0.9 28.4 1.8 29.0 2.1 29.5 1.4 # 1366: 02MAR2016 27.3 1.0 28.6 1.8 28.9 1.9 29.5 1.4 # 1367: 09MAR2016 27.7 1.2 28.6 1.6 28.9 1.8 29.6 1.5 # 1368: 16MAR2016 27.5 1.0 28.8 1.7 28.9 1.7 29.6 1.4 # 1369: 23MAR2016 27.2 0.9 28.6 1.4 28.8 1.5 29.5 1.2
Обратите внимание, что
fread
автоматически удаляются начальные и конечные пробелы - иногда это нежелательно, и в этом случае устанавливаетсяstrip.white = FALSE
.Мы также могли бы начать с вектора ширины столбцов
ww
, выполнив:ww <- c(9, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4) nd <- cumsum(ww) col_ends <- list(beg = c(1, nd[-length(nd)]+1L), end = nd)
И мы могли бы выбрать, какие столбцы исключить более надежно, используя отрицательные индексы, например:
col_ends <- list(beg = c(1, -10, 15, 19, -23, 28, 32, -36, 41, 45, -49, 54, 58), end = c(9, 14, 18, 22, 27, 31, 35, 40, 44, 48, 53, 57, 61))
Затем замените
col_ends$beg[ii]
наabs(col_ends$beg[ii])
и в следующей строке:paste0("V", which(col_ends$beg < 0))
Наконец, если вы хотите, чтобы имена столбцов также считывались программно, вы можете очистить их с помощью
readLines
:cols <- gsub("\\s", "", sapply(1:(length(col_ends$beg)), function(ii) stri_sub(readLines(URL, n = 4L)[4L], col_ends$beg[ii]+1L, col_ends$end[ii]+1L))) cols <- cols[cols != ""]
(обратите внимание, что объединение этого шага с
fread
потребует создания копии таблицы, чтобы удалить строку заголовка, и, таким образом, будет неэффективно для больших наборов данных)источник
Я ничего не знаю о R, но могу предоставить вам регулярное выражение, которое будет соответствовать таким строкам:
\s[0-9]{2}[A-Z]{3}[0-9]{4}(\s{5}[0-9]+\.[0-9]+[ -][0-9]+\.[0-9]+){4}
источник