Ответ 1
Вы должны использовать пакет LaF
. Это вводит какой-то указатель на ваши данные, тем самым избегая - для очень больших данных - раздражающего поведения чтения всего файла. Насколько мне известно, fread()
в data.table
pckg необходимо знать общее количество строк, что требует времени для данных GB.
Используя указатель в LaF
, вы можете перейти к каждой строке (строкам), которую хотите; и читать в кусках данных, на которые вы можете применить свою функцию, а затем перейти к следующему фрагменту данных. На моем маленьком ПК я пропустил csv файл размером 25 ГБ с шагом 10e6 и извлек все необходимые наблюдения - 5e6 - каждый кусок 10e6 занял 30 секунд.
UPDATE:
library('LaF')
huge_file <- 'C:/datasets/protein.links.v9.1.txt'
#First detect a data model for your file:
model <- detect_dm_csv(huge_file, sep=" ", header=TRUE)
Затем создайте соединение с вашим файлом с помощью модели:
df.laf <- laf_open(model)
После выполнения вы можете делать всевозможные вещи, не зная размер файла, как в data.table pckgs. Например, поместите указатель на строку 100e6 и прочитайте здесь 1e6 строк данных:
goto(df.laf, 100e6)
data <- next_block(df.laf,nrows=1e6)
Теперь data
содержит 1e6 строк вашего CSV файла (начиная с строки 100e6).
Вы можете читать в кусках данных (размер зависит от вашей памяти) и поддерживать только то, что вам нужно. например huge_file
в моем примере указывает на файл со всеми известными последовательностями белка и имеет размеp > 27 ГБ - путь к большому для моего ПК. Чтобы получить только последовательность человека, я отфильтровал с использованием идентификатора организма, который для человека равен 9606, и это должно появиться в начале переменной protein1
. Грязный путь заключается в том, чтобы перевести его в простой цикл и просто прочитать один блок данных за раз:
library('dplyr')
library('stringr')
res <- df.laf[1,][0,]
for(i in 1:10){
raw <-
next_block(df.laf,nrows=100e6) %>%
filter(str_detect(protein1,"^9606\\."))
res <- rbind(res, raw)
}
Теперь res
содержит отфильтрованные данные человека. Но лучше - и для более сложных операций, например. вычисление по данным "на лету" - функция process_blocks()
принимает в качестве аргумента функцию. Следовательно, в функции вы делаете то, что хотите на каждой части данных. Прочтите документацию.