Подтвердить что ты не робот

Недостаточно памяти при изменении большого массива данных R.

У меня есть большой фрейм данных с объемом около 900 МБ. Затем я попытался изменить его следующим образом:

dataframe[[17]][37544]=0 

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

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

dataframe[37544, 17]=0

но R footprint все еще удваивается, и для выполнения команды требуется довольно много времени.

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

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

Тао

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Когда мне следует использовать оператор := в data.table?

Почему значение data.table определено :=, а не перегрузка < -?

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

И вот 12 вопросов о переполнении стека тегом 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.

Ответ 3

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

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

Ответ 4

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

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