Чтение больших данных с фиксированной шириной

Как читать большие данные с фиксированной шириной? Я прочитал этот вопрос и попробовал несколько советов, но все ответы предназначены для данных с разделителями (как .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 минут (и подсчет …). Любые новые предложения?

Без достаточной информации о ваших данных трудно дать конкретный ответ, но вот несколько идей, которые помогут вам начать:

Во-первых, если вы находитесь в системе 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 строк на входе.
  • Он поставляется с индикатором выполнения;)
  • Схемы Санки в R?
  • Извлеките регулярное выражение
  • Подсчитайте количество всех слов в строке
  • Как использовать data.table внутри функций и циклов?
  • Преобразуйте столбец данных в 1 или 0 для значений «истина» / «ложь» и назначьте в dataframe
  • Извлеките столбец dplyr tbl в виде вектора
  • Поиск обходного пути для файла gtable_add_grob, нарушенного ggplot 2.2.0
  • Как получить таблицу непредвиденных расходов?
  • Как сравнить функции?
  • Увеличить количество тиков оси
  • Добавить индекс к смежным прогонам равных значений
  • Давайте будем гением компьютера.