2012-05-26 6 views
4

У меня есть 9 столбцов data.frame (x) и у вас есть миллионы строк. Я смог прочитать его в R, успешно внести в него некоторые изменения, и код будет выполняться без проблем. Однако, когда я пытаюсь записать его в файл .csv, используяОшибка памяти при использовании write.csv

write.csv(x,file=argv[2],quote=F,row.names=F) 

я получаю ошибку, которая говорит

Error: cannot allocate vector of size 1.2Gb 

Это не имеет никакого смысла, так как данные уже находятся в памяти, вычисления сделано , и все, что я хочу сделать, это записать его на диск. Кроме того, пока я контролировал память, размер виртуальной памяти почти удваивался для этого процесса во время этой фазы записи. Будет ли писать пользовательскую функцию C, чтобы выписать эту помощь data.frame? Любые предложения/рекомендации/указатели оценены.

ps: Я запускаю все это в 64-разрядном блоке ubuntu с около 24G RAM. Общее пространство не может быть проблемой. Размер данных составляет около 10G

+2

Проще всего сделать это, чтобы записать его в файл небольшими частями, используя 'append = TRUE'. В остальном общая оперативная память, установленная на вашем компьютере, может быть вводящим в заблуждение индикатором того, будут ли у вас проблемы с памятью, поскольку R часто требуется _contiguous_ блоков памяти определенного размера. Даже с 24Gb, поиск 10 смежных Gb памяти может быть проблемой время от времени. – joran

+0

Что сказал @joran. Вы можете попробовать 'gc()' сразу же, но вряд ли это поможет. –

+1

Вы можете попробовать сохранить объект как изображение .RData и загрузить его в новый сеанс. По какой-то причине он потребляет меньше памяти, чем объект непосредственно после вычисления. Иногда я использую этот трюк, когда у меня возникают проблемы с памятью. –

ответ

9

Вы должны понимать, что функции R часто копируют аргументы, если они изменяют их, поскольку парадигма функционального программирования, используемая R, определяет, что функции не изменяют объекты, переданные в качестве аргументов; поэтому R копирует их, когда необходимо внести изменения в процессе выполнения функции.

Если вы создаете R с поддержкой отслеживания памяти, вы можете увидеть это копирование в действии для любой операции, с которой вы столкнулись. Используя набор данных airquality пример, отслеживание использования памяти я вижу

> head(airquality) 
    Ozone Solar.R Wind Temp Month Day 
1 41  190 7.4 67  5 1 
2 36  118 8.0 72  5 2 
3 12  149 12.6 74  5 3 
4 18  313 11.5 62  5 4 
5 NA  NA 14.3 56  5 5 
6 28  NA 14.9 66  5 6 
> tracemem(airquality) 
[1] "<0x12b4f78>" 
> write.csv(airquality, "airquality.csv") 
tracemem[0x12b4f78 -> 0x1aac0d8]: as.list.data.frame as.list lapply unlist which write.table eval eval eval.parent write.csv 
tracemem[0x12b4f78 -> 0x1aabf20]: as.list.data.frame as.list lapply sapply write.table eval eval eval.parent write.csv 
tracemem[0x12b4f78 -> 0xf8ae08]: as.list.data.frame as.list lapply write.table eval eval eval.parent write.csv 
tracemem[0x12b4f78 -> 0xf8aca8]: write.table eval eval eval.parent write.csv 
tracemem[0xf8aca8 -> 0xca7fe0]: [<-.data.frame [<- write.table eval eval eval.parent write.csv 
tracemem[0xca7fe0 -> 0xcaac50]: [<-.data.frame [<- write.table eval eval eval.parent write.csv 

Так что указывает на 6 копий данных делаются, как R готовит его для записи в файл.

Очевидно, что есть до 24 ГБ оперативной памяти, доступной; ошибка говорит, что для выполнения операции R требуется другой 1.2Gb ОЗУ.

Простейшим решением для начала было бы записать файл в куски. Напишите первый набор строк данных, используя append = FALSE, затем используйте append = TRUE для последующих вызовов write.csv(), выписывая оставшиеся куски. Возможно, вам придется поиграть с этим, чтобы найти размер куска, который не будет превышать доступную память.

+3

Вы, вероятно, также захотите установить 'col.names = FALSE' после первого фрагмента, чтобы вы не попадали в имена столбцов в середине вашего выходного файла. – Chase

+1

Хорошо, похоже, единственный способ сделать это будет, как @joran, и вы упомянули. Отрежьте файл на более мелкие куски и выпишите их один за другим в режиме добавления. – broccoli

+0

@ broccoli Я упомянул об этом как простейшем. Если вы обычно делаете что-то с большими данными, вам может понадобиться изучить пакеты ** ff ** или ** bigmemory **, которые предназначены для упрощения работы с очень большими данными. Я не очень хорошо знаком с ними, но у них могут быть специальные функции для записи больших объектов в файл. – joran

Смежные вопросы