2012-02-29 2 views
11

У меня есть большой фрейм данных, занимающий около 900 МБ памяти. Затем я попытался изменить это так:Недостаточно памяти при изменении большого R-данных.frame

dataframe[[17]][37544]=0 

Кажется, что делает R с использованием более чем 3G барана и R жалуется: (. Я на 32-битной машине) «Ошибка не может выделить вектор размером 3,0 Мб»,

Я нашел этот способ лучше:

dataframe[37544, 17]=0 

но след R по-прежнему в два раза, и команда занимает некоторое время, чтобы бежать.

На фоне C/C++ я действительно смущен этим поведением. Я подумал, что что-то вроде dataframe[37544, 17]=0 должно быть завершено в мигающем режиме, не затрачивая никакой дополнительной памяти (только одна ячейка должна быть изменена). Что делает R для тех команд, которые я написал? Каков правильный способ изменения некоторых элементов в кадре данных, а затем без дублирования памяти?

Большое вам спасибо за помощь!

Тао

+3

(Base) R классно не впечатляет при обработке больших структур данных. Вы захотите изучить некоторые комбинации пакетов ** ff **, ** bigmemory ** и ** data.table **. – joran

+3

Это неправда - data.frames классно неэффективны, но в (базовом) R есть очень эффективные структуры, которые вы должны использовать, если вам нужна эффективность. –

+0

@SimonUrbanek Да, я сформулировал это плохо. Я просто имел в виду именно то, что вы сказали, что фреймы данных, как правило, неэффективны, и что упомянутые мной пакеты часто могут быть полезны для людей, занимающихся большими данными. – joran

ответ

8

Посмотрите «копирование при записи» в контексте R обсуждений, связанных с памятью. Как только изменяется одна часть (потенциально очень большой) структуры данных, создается копия.

Полезное эмпирическое правило состоит в том, что если ваш самый большой объект - N mb/gb/... large, вам нужно около 3 * N ОЗУ. Такова жизнь с интерпретируемой системой.

Несколько лет назад, когда мне приходилось обрабатывать большие объемы данных на машинах (относительно объема данных) относительно низкоразмерных 32-битных машин, я получил хорошее применение из ранних версий пакета bigmemory. Он использует интерфейс «внешнего указателя» для хранения больших копий памяти за пределами R. Это избавляет вас не только от фактора «3x», но, возможно, больше, так как вы можете уйти с несмежной памятью (что другое нравится R).

+0

Спасибо большое! Я рассмотрел несколько вариантов, упомянутых в ответах. Я обнаружил, что bigmemory вам очень легко и достаточно для меня. – agmao

+7

@agmao Или вы можете попробовать ': =' в 'data.table', который делает именно то, что вы хотите. –

7

Кадры данных являются наихудшей структурой, которую вы можете выбрать для внесения изменений. Из-за довольно сложной обработки всех функций (таких как сохранение имен строк в синхронизации, частичное совпадение и т. Д.), Которые выполняются в чистом R-коде (в отличие от большинства других объектов, которые могут идти прямо на C), они, как правило, вынуждают дополнительные копии, такие как вы не можете редактировать их на месте. Проверьте R-devel на подробные обсуждения этого вопроса - он был обсужден в несколько раз.

Практическое правило: никогда не использовать кадры данных для больших данных, если только вы не рассматриваете их только для чтения. Вы будете на порядок более эффективными, если будете либо работать над векторами, либо с матрицами.

4

Существует тип объекта, который называется ffdf в пакете ff, который является в основном файлом data.frame, хранящимся на диске. В дополнение к другим советам выше вы можете попробовать это.

Вы также можете попробовать RSQLite.

12

Вперед на Joran, предлагая data.table, вот некоторые ссылки. Ваш объект с разрешением 900 Мбайт управляется в ОЗУ даже в 32 бит R без каких-либо копий.

When should I use the := operator in data.table?

Why has data.table defined := rather than overloading <-?

Кроме того, data.table v1.8.0 (пока не на CRAN, но стабильные на R-Forge) имеют set() функцию, которая обеспечивает еще более быстрое присвоение элементов, так же быстро, как присвоения matrix (например, для использования внутри контуров). См. latest NEWS для получения более подробной информации и примера. Также см. ?":=", который связан с ?data.table.

И вот здесь 12 questions на переполнение стека с тегом data.table, содержащим слово «ссылка».

Для полноты:

require(data.table) 
DT = as.data.table(dataframe) 
# say column name 17 is 'Q' (i.e. LETTERS[17]) 
# then any of the following : 

DT[37544, Q:=0]    # using column name (often preferred) 

DT[37544, 17:=0, with=FALSE] # using column number 

col = "Q" 
DT[37544, col:=0, with=FALSE] # variable holding name 

col = 17 
DT[37544, col:=0, with=FALSE] # variable holding number 

set(DT,37544L,17L,0)   # using set(i,j,value) in v1.8.0 
set(DT,37544L,"Q",0) 

Но, пожалуйста, см связаны вопросы и в документации пакета, чтобы увидеть, как := является более общим, чем этот простой пример; например, объединение := с двоичным поиском в соединении i.

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