R: выбор подмножества без копирования

Есть ли способ выбрать подмножество из объектов (фреймов данных, матриц, векторов) без создания копии выбранных данных?

Я работаю с довольно большими наборами данных, но никогда их не меняю. Однако часто для удобства я выбираю подмножества данных для работы. Создание копии большого подмножества каждый раз очень неэффективно с точки зрения использования памяти, но как обычное индексирование, так и subset (и, следовательно, xapply() семейство функций) создают копии выбранных данных. Поэтому я ищу функции или структуры данных, которые могут решить эту проблему.

Некоторые возможные подходы, которые могут соответствовать моим потребностям и, надеюсь, реализованы в некоторых пакетах R:

  • механизм копирования при записи, то есть структуры данных, которые копируются только при добавлении или перезаписи существующих элементов;
  • неизменяемые структуры данных, которые требуют повторного создания информации об индексации только для структуры данных, но не ее содержимого (например, создание подстроки из строки путем создания только небольшого объекта, который содержит длину и указатель на тот же массив символов) ;
  • xapply() аналоги, не создающие подмножеств.

person ffriend    schedule 05.03.2012    source источник
comment
Я думаю, вам следует взглянуть на пакет data.table (предположительно, кто-то скоро появится здесь, чтобы дать вам более подробную информацию ...)   -  person Ben Bolker    schedule 06.03.2012
comment
Очевидно, что вам следует исследовать интерфейсы баз данных. Практически каждая вещь в r является передачей по обещанию, которая фактически становится передачей по значению в тот момент, когда нужно что-то сделать с подмножеством.   -  person IRTFM    schedule 06.03.2012
comment
@BenBolker: спасибо, data.table кажется хорошим пакетом, но, к сожалению, в большинстве случаев он не соответствует моим потребностям. В частности, data.table имеет другую модель индексации и значительно усложняет (и замедляет) выполнение выбора, подобного data[1:50, 1:10] (то есть выбор как по строке, так и по столбцу) и многих операций линейной алгебры. Я думал об использовании матриц вместо своих фреймов данных, чтобы сэкономить место и время, но у матриц тоже есть свои ограничения, поэтому я тоже ищу альтернативные варианты.   -  person ffriend    schedule 06.03.2012
comment
@DWin: относительно передачи по значению. Вы имеете в виду, что R использует ленивую оценку? Но это не соответствует тому, что я вижу: код DF <- data[1:10000, ] занимает около 30 секунд, что намного дольше, чем нужно для создания промис-объекта. Также это означает, что структуры данных должны быть постоянными, чтобы не нарушать семантику языка, но это не так. Можешь объяснить, пожалуйста? Я определенно что-то упускаю. (Дайте мне знать, стоит ли опубликовать это как отдельный вопрос.)   -  person ffriend    schedule 06.03.2012
comment
Не уверен, что вы подразумеваете под постоянным. Вполне возможно создать объект внутри среды функции, и он автоматически станет сборщиком мусора при выходе. Насколько я понимаю, R использует ленивую оценку. Вы можете использовать функции delayedAssign и force, если хотите контролировать этот процесс. Большинство из нас не задумываются об этом (пока это не кусает нас во время оценки функций).   -  person IRTFM    schedule 06.03.2012
comment
@DWin: постоянные структуры данных — это те, которые нельзя изменить на месте. Если вы хотите обновить его, вам нужно создать измененную копию (которая обычно использует большинство элементов исходной структуры данных). Спасибо за эту ленивую оценку — я пришел из функционального программирования, и такие вещи, как промисы и принудительное выполнение, делают программирование в R еще более приятным!   -  person ffriend    schedule 06.03.2012


Ответы (1)


Попробуйте пакет ref. В частности, его класс refdata.

Что вам может не хватать в data.table, так это то, что при группировке (параметр by=) подмножества данных не копируются, так что это быстро. [Ну, технически они находятся в общей области памяти, которая повторно используется для каждой группы и копируется с помощью memcpy, который намного быстрее, чем циклы R for в C.]

:= в data.table — это один из способов изменить data.table на месте. data.table отличается от обычного стиля программирования R тем, что он не копируется при записи. Пользователь должен вызвать copy() явно, чтобы скопировать (потенциально очень большую) таблицу, даже внутри функции.

Вы правы, в data.table нет такого механизма, как refdata. Я понимаю, что вы имеете в виду, и это была бы хорошая функция. Однако refdata должен работать на data.table, и вы можете быть в порядке с data.frame (но обязательно отслеживайте копии с tracemem(DF)).

Также есть idata.frame (неизменяемый data.frame) в пакете plyr, который вы можете попробовать.

person Matt Dowle    schedule 06.03.2012