Недостаточно памяти при слиянии - PullRequest
6 голосов
/ 02 сентября 2011

У меня есть данные панели, которые выглядят так:

(Только существенно урезать для моего вопроса)

Persno 122 122 122 333 333 333 333 333 444 444 
Income 1500 1500 2000 2000 2100 2500 2500 1500 2000 2200
year 1990 1991 1992 1990 1991 1992 1993 1994 1992 1993

Теперь я хотел бы выделить для каждого ряда (PErsno) годы опыта в начале года. Я использую ddply

hilf3<-ddply(data, .(Persn0), summarize, Bgwork = 1:(max(year) - min(year)))

Чтобы получить вывод, похожий на этот:

Workexperience: 1 2 3 1 2 3 4 5 1 2

Теперь я хочу объединить результаты ddply с исходными данными панели:

data<-(merge(data,hilf3,by.x="Persno",by.y= "Persno"))

Набор данных панели очень большой. Код останавливается из-за ошибки размера памяти.

ErrorMessage:

1: в make.unique (как символ (строки)):

Достигнуто общее выделение 4000 МБ: см. Справку (memory.size)

Что мне делать?

Ответы [ 4 ]

5 голосов
/ 02 сентября 2011

Перечитывая ваш вопрос, я думаю, что вы вообще не хотите использовать merge здесь вообще. Просто отсортируйте исходный фрейм данных и скопируйте Bgwork с hilf3. Кроме того, ваш ddply -звук может привести к последовательности 1:0, что, скорее всего, не то, что вы хотите. Попробуйте

data = data[order(data$Persno, data$year),]
hilf3 = ddply(data, .(Persno), summarize, Bgwork=(year - min(year) + 1))
stopifnot(nrow(data) == nrow(hilf3))
stopifnot(all(data$Persno == hilf3$Persno))
data$Bgwork = hilf3$Bgwork
4 голосов
/ 02 сентября 2011

Ну, пожалуй, самый верный способ исправить это - получить больше памяти. Тем не менее, это не всегда вариант. То, что вы можете сделать, зависит от вашей платформы. В Windows проверьте результаты memory.size() и сравните это с доступной оперативной памятью. Если объем памяти меньше, чем ОЗУ, вы можете увеличить его. Это не вариант в Linux, так как по умолчанию он будет отображать всю вашу память.

Другая проблема, которая может усложнить ситуацию, связана с тем, используете ли вы 32-битную или 64-битную систему, поскольку 32-битные окна могут адресовать только определенный объем ОЗУ (2-4 ГБ) в зависимости от настроек . Это не проблема, если вы используете 64-битную Windows 7, которая может адресовать гораздо больше памяти.

Более практичным решением является удаление всех ненужных объектов из вашего рабочего пространства перед выполнением слияния. Вы должны запустить gc(), чтобы увидеть, сколько памяти у вас есть и используется, а также удалить все объекты, на которые больше нет ссылок. Лично я, вероятно, запустил бы ваш ddply() из сценария, затем сохранил бы полученный фрейм данных в виде файла CSV, закрыл вашу рабочую область и снова открыл ее, а затем снова выполнил слияние.

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

Надеюсь, это поможет.

2 голосов
/ 02 сентября 2011

Если вам нужно объединить большие фреймы данных в R, один хороший вариант - сделать это, например, 10000 строк.Если вы объединяете фреймы данных x и y, делайте циклы по 10000 строкам фрагментов x, объединяйте (или, скорее, используйте plyr::join) с y и немедленно добавляйте эти результаты в CSV-файл sigle.После того, как все части были объединены и записаны в файл, прочитайте этот csv-файл.Это очень эффективно использует память при правильном использовании векторов логического индекса и хорошо размещенных rm и gc вызовов.Это не быстро, хотя.

0 голосов
/ 28 февраля 2018

С тех пор, как этот вопрос был опубликован, пакет data.table обеспечил повторную реализацию фреймов данных и функцию merge, которая, как я обнаружил, намного более эффективна в использовании памяти, чем стандартная R. Преобразование фреймов данных по умолчанию в таблицы данных с as.data.table может избежать проблем с памятью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...