Обрезка огромного (3,5 ГБ) файла csv для чтения в R

Итак, у меня есть файл данных (разделенный точкой с запятой), в котором много деталей и неполных строк (ведущий Access и SQL для подавления). Это dataset уровня графства, разбитый на сегменты, подсегменты и подсегменты (на общую сумму ~ 200 коэффициентов) в течение 40 лет. Короче говоря, он огромный, и он не будет вписываться в память, если я попытаюсь просто прочитать его.

Поэтому мой вопрос заключается в том, что я хочу, чтобы все графства, но всего один год (и только самый высокий уровень сегмента …, в результате чего в конце было около 100 000 строк), что было бы лучшим способом получить этот сверток в R?

В настоящее время я пытаюсь вырезать нерелевантные годы с Python, обойдя ограничение размера файлов, читая и работая по одной строке за раз, но я бы предпочел решение R-only (пакеты CRAN в порядке). Есть ли аналогичный способ читать в файлах кусок за раз в R?

Любые идеи очень приветствуются.

Обновить:

  • Ограничения
    • Нужно использовать мою машину, поэтому никаких экземпляров EC2
    • Как только R-только возможно. Скорость и ресурсы не являются проблемой в этом случае … если моя машина не взрывается …
    • Как вы можете видеть ниже, данные содержат смешанные типы, которые мне нужно использовать позже
  • Данные
    • Данные 3,5 ГБ, около 8,5 миллионов строк и 17 столбцов
    • Несколько тысяч строк (~ 2k) искажены, причем только один столбец вместо 17
      • Они абсолютно несущественны и могут быть отброшены
    • Мне нужно только ~ 100 000 строк из этого файла (см. Ниже)

Пример данных:

County; State; Year; Quarter; Segment; Sub-Segment; Sub-Sub-Segment; GDP; ... Ada County;NC;2009;4;FIRE;Financial;Banks;80.1; ... Ada County;NC;2010;1;FIRE;Financial;Banks;82.5; ... NC [Malformed row] [8.5 Mill rows] 

Я хочу вырезать несколько столбцов и выбрать два из 40 доступных лет (2009-2010 с 1980 по 2020 год), чтобы данные могли вписаться в R:

 County; State; Year; Quarter; Segment; GDP; ... Ada County;NC;2009;4;FIRE;80.1; ... Ada County;NC;2010;1;FIRE;82.5; ... [~200,000 rows] 

Результаты:

После выполнения всех предложенных предложений я решил, что readLines, предложенный JD и Marek, будет работать лучше всего. Я дал Мареку чек, потому что он дал примерную реализацию.

Я воспроизвел немного адаптированную версию реализации Marek для моего окончательного ответа здесь, используя strsplit и cat, чтобы сохранить только столбцы, которые я хочу.

Следует также отметить, что это намного эффективнее, чем Python … как в Python chomps через файл 3,5 ГБ за 5 минут, в то время как R занимает около 60 … но если все, что у вас есть, это R, то это билет.

 ## Open a connection separately to hold the cursor position file.in <- file('bad_data.txt', 'rt') file.out <- file('chopped_data.txt', 'wt') line <- readLines(file.in, n=1) line.split <- strsplit(line, ';') # Stitching together only the columns we want cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE) ## Use a loop to read in the rest of the lines line <- readLines(file.in, n=1) while (length(line)) { line.split  1) { if (line.split[[1]][3] == '2009') { cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE) } } line<- readLines(file.in, n=1) } close(file.in) close(file.out) 

Отказы по подходу:

  • sqldf
    • Это определенно то, что я буду использовать для этого типа проблемы в будущем, если данные будут хорошо сформированы. Однако, если это не так, то SQLite задыхается.
  • Уменьшение карты
    • Честно говоря, docs запугали меня в этом немного, поэтому я не стал его пытаться. Похоже, что объект должен быть в памяти, и это могло бы победить, если бы это было так.
  • bigmemory
    • Этот подход полностью связан с данными, но он может обрабатывать только один тип за раз. В результате все мои векторы персонажей упали, когда помещены в большую таблицу. Если мне нужно создавать большие наборы данных для будущего, я бы рассмотрел только использование чисел, чтобы сохранить этот вариант в живых.
  • сканирование
    • У сканера, похоже, были подобные проблемы типа большой памяти, но со всеми механиками readLines. Короче говоря, на этот раз он просто не подходил.

Моя попытка с readLines . Этот fragment кода создает csv с выбранными годами.

 file_in <- file("in.csv","r") file_out <- file("out.csv","a") x <- readLines(file_in, n=1) writeLines(x, file_out) # copy headers B <- 300000 # depends how large is one pack while(length(x)) { ind <- grep("^[^;]*;[^;]*; 20(09|10)", x) if (length(ind)) writeLines(x[ind], file_out) x <- readLines(file_in, n=B) } close(file_in) close(file_out) 

Есть ли аналогичный способ читать в файлах кусок за раз в R?

Да. Функция readChar () будет считываться в блоке символов, не предполагая, что они завершены нулем. Если вы хотите читать данные в строке за раз, вы можете использовать readLines () . Если вы читаете блок или строку, выполните операцию, а затем напишите данные, вы можете избежать проблемы с памятью. Хотя, если вам нравится снимать большой экземпляр памяти на EC2 Amazon, вы можете получить до 64 ГБ оперативной памяти. Это должно содержать ваш файл плюс много места для манипулирования данными.

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

Если вы захотите прочитать много концертов с разделителями данных в R, вы должны хотя бы исследовать пакет sqldf, который позволяет импортировать непосредственно в sqldf из R, а затем работать с данными из R. Я нашел sqldf как один из самых быстрых способов импорта концертов данных в R, как упоминалось в этом предыдущем вопросе .

Я не эксперт в этом, но вы можете подумать о попытке MapReduce , что в основном означает принятие подхода «разделяй и властвуй». R имеет несколько вариантов для этого, в том числе:

  1. mapReduce (чистый R)
  2. RHIPE (который использует Hadoop ); см. пример 6.2.2 в документации для примера подмножества файлов

В качестве альтернативы R предоставляет несколько пакетов для обработки больших данных, которые выходят за пределы памяти (на диск). Вероятно, вы могли бы загрузить весь dataset в объект bigmemory и полностью выполнить сокращение внутри R. См. http://www.bigmemory.org/ для набора инструментов для обработки этого.

Пакет ff – это прозрачный способ работы с огромными файлами.

Вы можете увидеть веб-сайт пакета и / или презентацию об этом.

надеюсь, это поможет

Вы можете импортировать данные в базу данных SQLite, а затем использовать RSQLite для выбора подмножеств.

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

http://colbycol.r-forge.r-project.org/

Он передает любые аргументы в read.table, поэтому комбинация должна позволять вам подмножество довольно жестко.

Как насчет использования readr и read_*_chunked family?

Итак, в вашем случае:

TestFile.CSV

 County; State; Year; Quarter; Segment; Sub-Segment; Sub-Sub-Segment; GDP Ada County;NC;2009;4;FIRE;Financial;Banks;80.1 Ada County;NC;2010;1;FIRE;Financial;Banks;82.5 lol Ada County;NC;2013;1;FIRE;Financial;Banks;82.5 

Фактический код

 require(readr) f <- function(x, pos) subset(x, Year %in% c(2009, 2010)) read_csv2_chunked("testfile.csv", DataFrameCallback$new(f), chunk_size = 1) 

Это применимо f к каждому fragmentу, запоминая имена col и комбинируя отфильтрованные результаты в конце. См. « ?callback который является источником этого примера.

Это приводит к:

 # A tibble: 2 × 8 County State Year Quarter Segment `Sub-Segment` `Sub-Sub-Segment` GDP *         1 Ada County NC 2009 4 FIRE Financial Banks 801 2 Ada County NC 2010 1 FIRE Financial Banks 825 

Вы даже можете увеличить chunk_size но в этом примере есть только 4 строки.

Вы взяли большую память ? Проверьте это и это .

Возможно, вы можете перейти на MySQL или PostgreSQL, чтобы не допустить вас от ограничений MS Access.

Достаточно просто подключить R к этим системам с помощью DBI (доступного на CRAN).

scan () имеет как аргумент nlines, так и аргумент пропуска. Есть ли какая-то причина, по которой вы можете просто использовать это для чтения в куске строк, проверяя дату, чтобы узнать, подходит ли это? Если входной файл упорядочен по дате, вы можете сохранить индекс, который сообщает вам, какими должны быть ваши пропуски и nlines, которые ускорят процесс в будущем.

В наши дни 3,5 ГБ просто не так уж и велики, я могу получить доступ к машине с 244 ГБ оперативной памяти (r3.8xlarge) в облаке Amazon за 2,80 долл. / Час. Сколько часов вам понадобится, чтобы выяснить, как решить проблему с помощью решений типа больших данных? Сколько стоит ваше время? Да, вам понадобится час или два, чтобы понять, как использовать AWS, но вы можете изучить основы на свободном уровне, загрузить данные и прочитать первые 10k строк в R, чтобы проверить, работает ли это, а затем вы можете запустить большой экземпляр памяти, такой как r3.8xlarge и прочитал все это! Просто мой 2c.

Теперь, 2017, я бы предложил пойти на искру и искра.

  • синтаксис может быть написан простым просто dplyr-подобным образом

  • он достаточно хорошо подходит для небольшой памяти (небольшой по смыслу 2017 года)

Однако, это может быть запугивающим опытом для начала …

Я бы пошел на БД, а затем сделал несколько запросов, чтобы извлечь образцы, которые вам нужны через DBI

Пожалуйста, не загружайте CSV-файл 3,5 ГБ в SQLite. Или, по крайней мере, дважды проверьте, что ваш HUGE db вписывается в пределы SQLite, http://www.sqlite.org/limits.html

Это чертовски большая БД у вас. Я бы пошел на MySQL, если вам нужна скорость. Но будьте готовы ждать много часов, чтобы импорт был закончен. Если у вас нет нетрадиционного оборудования или вы пишете из будущего …

EC2 от Amazon может быть хорошим решением для создания экземпляра сервера с R и MySQL.

мои две скромные копейки.

  • экспортировать кадры данных в Excel через xlsx с условным форматированием
  • Ошибка в if / while (условие) {: отсутствует Значение, в котором требуется TRUE / FALSE
  • Сценарий расписания R с использованием cron
  • Сохранение нескольких ggplots из ls в один и отдельные файлы в R
  • Возвращать временные frameworks подмножества данных в другие временные frameworks?
  • Замена чисел в диапазоне с коэффициентом
  • Заменить конкретные символы в строках
  • Положите разрыв в Y-оси гистограммы
  • Преобразование года и месяца (формат «yyyy-mm») на дату?
  • Как я могу извлечь диапазоны осей для объекта ggplot2?
  • Подзаголовок вне границ - общее определение и решение?
  • Interesting Posts

    Как запустить сервер MySQL в Windows?

    Android: сохранение имени пользователя и пароля?

    ASP.NET – AppDomain.CurrentDomain.GetAssemblies () – Ассембли отсутствуют после перезапуска AppDomain

    Как масштабировать изображение в ImageView, чтобы сохранить соотношение сторон

    Не селектор CSS

    Что вызывает java.lang.StackOverflowError

    Ошибка Недопустимые области: offline_access, publish_stream, когда я пытаюсь подключиться к API Facebook

    Принудительное JSF обрабатывать, проверять и обновлять компоненты для чтения / отключения ввода в любом случае

    Низкий баран в обновлении Windows 8.1

    Изменить часовой пояс в объекте POSIXct

    Утилита командной строки Windows для управления пропускной способностью сети

    Как использовать распознавание речи google api в python?

    Удалите HTML-тег, но сохраните innerHtml

    Какова цель административной установки, инициированной с помощью msiexec / a?

    Невозможно связать с ‘formGroup’, поскольку это не известное свойство ‘form’

    Давайте будем гением компьютера.