Таким образом, у меня есть файл данных (разделенная точка с запятой), который имеет много детали и неполных строк (ведущий Доступ и SQL для дросселирования). Это - набор данных уровня графства, в который врываются сегменты, подсегменты и sub-sub-segments (для в общей сложности ~200 факторов) в течение 40 лет. Короче говоря, это огромно, и это не собирается вписываться в память, если я пытаюсь просто считать его.
Таким образом, мой вопрос - это, учитывая, что я хочу все округа, но только год (и просто высший уровень сегмента... ведущего приблизительно к 100 000 строк в конце), каков был бы лучший способ пойти о получении этой свертки в R?
В настоящее время я пытаюсь прервать несоответствующие годы с Python, обходя предел размера файла путем чтения и работы на одну строку за один раз, но я предпочел бы решение R-only (пакеты CRAN хорошо). Существует ли похожий способ считать в файлах часть за один раз в R?
Любые идеи значительно ценились бы.
Обновление:
Пример данных:
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 проверку, потому что он дал демонстрационную реализацию.
Я воспроизвел немного адаптированную версию реализации Marek для моего окончательного ответа здесь, с помощью strsplit и кошки для хранения только столбцов, которые я хочу.
Нужно также отметить, что это НАМНОГО менее эффективно, чем 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)
Сбои подходом:
Моя попытка с readLines
. Этот кусок кода создает 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)
Вы можете импортировать данные в базу данных SQLite , а затем использовать RSQLite для выбора подмножеств.
scan () имеет аргумент nlines и аргумент пропуска. Есть ли причина, по которой вы можете просто использовать это, чтобы читать по куску строк за раз, проверяя дату, чтобы увидеть, подходит ли она? Если входной файл упорядочен по дате, вы можете сохранить индекс, который сообщает вам, какими должны быть ваши пропуски и строки, что ускорит процесс в будущем.
Возможно, вы сможете перейти на MySQL или PostgreSQL, чтобы избежать ограничений MS Access.
Довольно просто подключить R к этим системам с помощью коннектора базы данных на основе DBI (доступен в CRAN).
Я бы пошел за БД, а затем сделал несколько запросов, чтобы извлечь нужные вам образцы через DBI
Пожалуйста, избегайте импорта 3 , CSV-файл размером 5 ГБ в SQLite. Или, по крайней мере, дважды проверьте, что ваша ОГРОМНАЯ база данных соответствует ограничениям SQLite, http://www.sqlite.org/limits.html
У вас чертовски большая база данных. Я бы выбрал MySQL, если вам нужна скорость. Но будьте готовы ждать много часов, пока завершится импорт. Если у вас нет нестандартного оборудования или вы пишете из будущего ...
Amazon EC2 может быть хорошим решением также для создания экземпляра сервера с R и MySQL.
мои два скромных гроша стоят.
Есть ли аналогичный способ чтения файлов по частям в R?
Да. Функция readChar () будет читать блок символов, не предполагая, что они оканчиваются нулем. Если вы хотите читать данные построчно, вы можете использовать readLines () . Если вы читаете блок или строку, выполняете операцию, а затем записываете данные, вы можете избежать проблемы с памятью. Хотя, если вы хотите запустить большой экземпляр памяти на Amazon EC2, вы можете получить до 64 ГБ ОЗУ. Это должно содержать ваш файл и много места для манипулирования данными.
Если вам нужно больше скорости, то рекомендация Шейна использовать Map Reduce очень хорошая. Однако, если вы выберете путь использования большого экземпляра памяти на EC2, вам следует взглянуть на многоядерный пакет для использования всех ядер на машине.
Если вы обнаружите, что хотите прочитать много гигабайт данных с разделителями в R, вам следует хотя бы изучить пакет sqldf, который позволяет импортировать непосредственно в sqldf из R, а затем работать с данными из R. Я нашел sqldf чтобы быть одним из самых быстрых способов импорта гигабайт данных в R, как упоминалось в в предыдущем вопросе .
Я не эксперт в этом, но вы можете попробовать MapReduce , что в основном означало бы использование подхода «разделяй и властвуй». У R есть несколько вариантов для этого, в том числе:
В качестве альтернативы R предоставляет несколько пакетов для работы с большими данными, которые выходят за пределы памяти (на диск). Вероятно, вы могли бы загрузить весь набор данных в объект bigmemory
и полностью выполнить сокращение в R. См. http://www.bigmemory.org/ для набора инструментов для обработки этого .