Чтение больших данных с фиксированной шириной
Как читать большие данные с фиксированной шириной? Я прочитал этот вопрос и попробовал несколько советов, но все ответы предназначены для данных с разделителями (как .csv), и это не мое дело. Данные имеют 558 МБ, и я не знаю, сколько строк.
Я использую:
dados <- read.fwf('TS_MATRICULA_RS.txt', width=c(5, 13, 14, 3, 3, 5, 4, 6, 6, 6, 1, 1, 1, 4, 3, 2, 9, 3, 2, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 11, 9, 2, 3, 9, 3, 2, 9, 9, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1), stringsAsFactors=FALSE, comment.char='', colClasses=c('integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'character', 'character', 'character', 'integer', 'integer', 'character', 'integer', 'integer', 'character', 'integer', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'character', 'integer', 'integer', 'character', 'character', 'character', 'character', 'integer', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character'), buffersize=180000)
Но для чтения данных требуется 30 минут (и подсчет …). Любые новые предложения?
- R Условная оценка при использовании оператора трубы%>%
- вычислить среднее значение для каждого столбца матрицы в R
- Удаление html-тегов из строки в R
- Планирование R Script
- Как добавить новый столбец в фреймворк данных (на передний план не заканчивается)?
- Преобразование числового представления столбца «переменная» в исходную строку после таяния с использованием шаблонов
- Вставка двух векторов с комбинациями всех элементов векторов
- Как удалить выбросы из набора данных
- Создание симметричной матрицы в R
- Использование циклов с knitr для создания нескольких отчетов в формате PDF ... нужно немного помочь, чтобы получить меня за горб
- Как удалить все дубликаты, чтобы NONE остался в фрейме данных?
- R - список к кадру данных
- Перекрывающиеся совпадения в R
Без достаточной информации о ваших данных трудно дать конкретный ответ, но вот несколько идей, которые помогут вам начать:
Во-первых, если вы находитесь в системе Unix, вы можете получить некоторую информацию о своем файле, используя команду wc
. Например, wc -l TS_MATRICULA_RS.txt
расскажет вам, сколько строк в вашем файле, а wc -L TS_MATRICULA_RS.txt
сообщит длину самой длинной строки в вашем файле. Это может быть полезно знать. Аналогично, head
и tail
позволяют вам проверять первую и последнюю 10 строк вашего текстового файла.
Во-вторых, некоторые предложения: поскольку кажется, что вы знаете ширину каждого поля, я бы рекомендовал один из двух подходов.
Вариант 1: csvkit
+ ваш любимый метод для быстрого чтения больших данных
csvkit
– это набор инструментов Python для работы с файлами CSV. Один из инструментов – in2csv
, который принимает файл с фиксированной шириной в сочетании с файлом «schema» для создания правильного CSV, который может использоваться с другими программами.
Файл схемы сам по себе представляет собой файл CSV с тремя столбцами: (1) имя переменной, (2) начальную позицию и (3) ширину. Пример (с in2csv
страницы in2csv
):
column,start,length name,0,30 birthday,30,10 age,40,3
Создав этот файл, вы сможете использовать что-то вроде:
in2csv -f fixed -s path/to/schemafile.csv path/to/TS_MATRICULA_RS.txt > TS_MATRICULA_RS.csv
Оттуда я бы предложил изучить данные с fread
с «data.table» или с помощью sqldf
.
Вариант 2: sqldf
с использованием substr
Использование sqldf
в файле данных большого размера, как и ваш, должно быть довольно быстрым, и вы получаете возможность указать, что именно вы хотите читать с помощью substr
.
Опять же, это будет ожидать, что у вас есть файл схемы, как описано выше. После того, как у вас есть файл схемы, вы можете сделать следующее:
temp <- read.csv("mySchemaFile.csv") ## Construct your "substr" command GetMe <- paste("select", paste("substr(V1, ", temp$start, ", ", temp$length, ") `", temp$column, "`", sep = "", collapse = ", "), "from fixed", sep = " ") ## Load "sqldf" library(sqldf) ## Connect to your file fixed <- file("TS_MATRICULA_RS.txt") myDF <- sqldf(GetMe, file.format = list(sep = "_"))
Поскольку вы знаете ширину, вы можете пропустить создание файла схемы. Из ширины это всего лишь небольшая работа с cumsum
. Вот базовый пример, read.fwf
на первом примере с read.fwf
:
ff <- tempfile() cat(file = ff, "123456", "987654", sep = "\n") read.fwf(ff, widths = c(1, 2, 3)) widths <- c(1, 2, 3) length <- cumsum(widths) start <- length - widths + 1 column <- paste("V", seq_along(length), sep = "") GetMe <- paste("select", paste("substr(V1, ", start, ", ", widths, ") `", column, "`", sep = "", collapse = ", "), "from fixed", sep = " ") library(sqldf) ## Connect to your file fixed <- file(ff) myDF <- sqldf(GetMe, file.format = list(sep = "_")) myDF unlink(ff)
Пакет LaF довольно хорошо читает файлы с фиксированной шириной очень быстро. Я использую его ежедневно для загрузки файлов +/- 100Mio записей с 30 столбцами (не так много столбцов символов, как у вас – в основном числовые данные и некоторые факторы). И это довольно быстро. Так вот что я буду делать.
library(LaF) library(ffbase) my.data.laf <- laf_open_fwf('TS_MATRICULA_RS.txt', column_widths=c(5, 13, 14, 3, 3, 5, 4, 6, 6, 6, 1, 1, 1, 4, 3, 2, 9, 3, 2, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 11, 9, 2, 3, 9, 3, 2, 9, 9, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1), stringsAsFactors=FALSE, comment.char='', column_types=c('integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'categorical', 'categorical', 'categorical', 'integer', 'integer', 'categorical', 'integer', 'integer', 'categorical', 'integer', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'categorical', 'integer', 'integer', 'categorical', 'categorical', 'categorical', 'categorical', 'integer', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical')) my.data <- laf_to_ffdf(my.data.laf, nrows=1000000) my.data.in.ram <- as.data.frame(my.data)
PS. Я начал использовать пакет LaF, потому что меня раздражало медленность read.fwf и потому, что код PL / SQL PostgreSQL, с которым я работал с первоначально анализируя данные, становился проблемой для поддержки.
Вот чистое R-решение, использующее новый пакет readr
, созданный Хэдли Викхэмом и командой RStudio, выпущенный в апреле 2015 года. Подробнее здесь . Код такой же простой, как это:
library(readr) my.data.frame <- read_fwf('TS_MATRICULA_RS.txt', fwf_widths(c(5, 13, 14, 3, 3, 5, 4, 6, 6, 6, 1, 1, 1, 4, 3, 2, 9, 3, 2, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 11, 9, 2, 3, 9, 3, 2, 9, 9, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1)), progress = interactive())
Преимущества read_fwf{readr}
-
readr
базируется вLaF
но на удивление быстрее . Он показал, что метод fasted считывает файлы фиксированной ширины в R - Это проще, чем альтернативы. например, вам не нужно беспокоиться о
column_types
потому что они будут вменены из первых 30 строк на входе. - Он поставляется с индикатором выполнения;)