R: Передача кадра данных по ссылке

R имеет семантику pass-by-value, которая минимизирует случайные побочные эффекты (хорошая вещь). Однако, когда код организован во многие функции/методы для повторного использования/удобочитаемости/ремонтопригодности, и когда этому коду необходимо манипулировать большими структурами данных, например, с помощью больших кадров данных, посредством серии преобразований/операций семантика pass-by-value ведет к большому количеству копий данных и много размаха кучи (плохая вещь). Например, кадр данных, который принимает 50 Мб в куче, который передается как параметр функции, будет скопирован как минимум столько же раз, сколько глубина вызова функции, а размер кучи в нижней части стека вызовов будет равен N * 50Mb. Если функции возвращают преобразованный/модифицированный фрейм данных из глубины в цепочке вызовов, то копирование увеличивается на другой N.

Вопрос SO Каков наилучший способ избежать передачи фрейма данных вокруг? затрагивает эту тему, но сформулирован таким образом, чтобы избежать прямого запроса прохода -рефисный вопрос и ответ на выигрыш в основном говорит: "Да, пошаговая оценка - это то, как работает R". Это на самом деле не на 100% точнее. R среды позволяют использовать семантику сквозной ссылки и фреймворки OO, такие как proto широко использовать эту возможность. Например, когда proto-объект передается как аргумент функции, а его "волшебная оболочка" передается по значению, разработчику R семантика является передачей по ссылке.

Кажется, что передача большого массива данных по ссылке была бы общей проблемой, и мне интересно, как к ней подошли другие, и есть ли какие-либо библиотеки, которые это делают. В моем поиске я его не обнаружил.

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

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

Ответ 1

Предпосылка вопроса (частично) неверна. R работает как пошаговый, и повторное копирование выполняется так, как вы указываете, только когда дальнейшие назначения и изменения в dataframe выполняются по мере передачи обещания. Таким образом, количество копий не будет размером N *, где N - глубина стека, а скорее где N - количество уровней, в которых выполняются назначения. Однако вы правы, что среда может быть полезна. Я вижу по ссылке, что вы уже нашли пакет "proto". Существует также относительно недавнее введение "ссылочного класса", иногда называемого "R5", где R/S3 является исходной системой классов S3, которая скопирована в R и R4, будет более современной системой классов, которая, как представляется, в основном поддерживает разработка пакета BioConductor.

Вот ссылка на пример Стивом Лианоглоу (в обсуждении достоинств ссылочных классов) встраивания среды внутри объекта S4, чтобы избежать затрат на копирование:

https://stat.ethz.ch/pipermail/r-help/2011-September/289987.html

Пакет data.table от Matthew Dowle создает новый класс объекта данных, чья семантика доступа, использующая "[", отличается от тех, что используются в обычных R data.frames, и которая действительно работает как сквозная ссылка. Он имеет превосходную скорость доступа и обработки. Он также может вернуться к семантике dataframe, поскольку в последующие годы такие объекты теперь наследуют класс data.frame.

Вы также можете изучить пакет данных Hesterberg.