Итак, у меня есть файл данных (разделенный точкой с запятой), в котором много деталей и неполные строки (ведущие к подавлению Access и SQL). Это набор данных на уровне округа, разбитый на сегменты, подсегменты и подсегменты (всего ~ 200 факторов) за 40 лет. Короче говоря, он огромен, и он не уместится в памяти, если я попытаюсь просто прочитать его.
Итак, мой вопрос заключается в следующем, учитывая, что мне нужны все округа, но только один год (и только самый высокий уровень сегмента ... что в итоге приводит к примерно 100000 строкам), что было бы наилучшим способом получить это сворачивание в R?
В настоящее время я пытаюсь вырезать ненужные годы с Python, обойдя ограничение на размер файла, читая и работая по одной строке за раз, но я бы предпочел решение только для R (пакеты CRAN в порядке). Есть ли аналогичный способ чтения файлов по частям в R?
Любые идеи очень приветствуются.
Обновить:
- Ограничения
- Требуется использовать мою машину, поэтому экземпляров EC2 нет
- Как можно больше R-only. Скорость и ресурсы в данном случае не важны ... при условии, что моя машина не взорвется ...
- Как вы можете видеть ниже, данные содержат смешанные типы, с которыми мне нужно работать позже.
- Данные
- Размер данных составляет 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, будут работать лучше всего. Я дал Мареку проверку, потому что он дал образец реализации.
Я воспроизвел слегка адаптированную версию реализации Марека для своего окончательного ответа здесь, используя strsplit и cat, чтобы сохранить только нужные мне столбцы.
Следует также отметить, что это НАМНОГО менее эффективно, чем Python ... например, Python перебирает файл размером 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 <- strsplit(line, ';')
if (length(line.split[[1]]) > 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 задыхается.
- Уменьшение карты
- Если честно, документация меня немного напугала, так что я не успел попробовать. Похоже, что для этого также требуется, чтобы объект был в памяти, что привело бы к поражению точки, если бы это было так.
- bigmemory
- Этот подход полностью связан с данными, но одновременно может обрабатывать только один тип. В результате все мои векторы символов упали при помещении в big.table. Если мне нужно разрабатывать большие наборы данных на будущее, я бы подумал об использовании только чисел, чтобы эта опция оставалась в живых.
- сканировать
- Сканирование, похоже, имело такие же проблемы с типами, как и большая память, но со всей механикой readLines. Короче говоря, на этот раз это просто не соответствовало требованиям.
sed
и / илиawk
создания урезанной версии CSV, которую вы можете прочитать напрямую. Поскольку это скорее обходной путь, чем ответ, я оставлю его как комментарий.