Кеширование дорогих операций в R - PullRequest
8 голосов
/ 27 июля 2010

Очень простой вопрос:

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

Этот подход работает очень хорошо для меня, но мне иногда приходится выполнять дорогостоящие операции (например, read.csv или reshape над базами данных 2M), которые я бы лучше кэшировал в среде R, а не перезапускал каждый раз, когда я запускаю скрипт (обычно это много раз, когда я прогрессирую и тестирую новые строки кода).

Есть ли способ кешировать, что скрипт делает до определенной точки, поэтому каждый раз, когда я запускаю только инкрементные строки кода (так же, как я делал бы при интерактивном запуске R)?

Спасибо.

Ответы [ 6 ]

9 голосов
/ 28 июля 2010
## load the file from disk only if it 
## hasn't already been read into a variable
if(!(exists("mytable")){
  mytable=read.csv(...)
}

Редактировать: исправлена ​​опечатка - спасибо Дирк.

8 голосов
/ 27 июля 2010

Некоторые простые способы выполнимы с некоторыми комбинациями

  • exists("foo") чтобы проверить, существует ли переменная, иначе перезагружаем или заново вычисляем
  • file.info("foo.Rd")$ctime, который вы можете сравнить с Sys.time() и посмотреть, является ли он более новым, чем указанное количество времени, которое вы можете загрузить, иначе пересчитать.

В CRAN есть также пакеты для кэширования, которые могут быть полезны.

4 голосов
/ 01 ноября 2011

(Запоздалый ответ, но я начал использовать SO через год после того, как этот вопрос был опубликован.)

Это основная идея, стоящая за запоминанием (или запоминанием).У меня длинный список предложений, особенно пакетов memoise и R.cache, в этом запросе .

Вы также можете воспользоваться контрольными точками, которые также рассматриваются какчасть этого же списка.

Я думаю, что ваш вариант использования отражает мою вторую: "запоминание чудовищных вычислений".:)

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

4 голосов
/ 28 июля 2010

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

Например, если вы загрузили CSV во фрейм данных с именем myVeryLargeDataFrame, а затем создали сводную статистику из этого фрейма данных в df с именем VLDFSummary, то вы можете сделать это:

save(c(myVeryLargeDataFrame, VLDFSummary), 
  file="~/myProject/cachedData/VLDF.RData", 
  compress="bzip2")

Опция сжатия там необязательна и должна использоваться, если вы хотите сжать файл, записываемый на диск.Смотрите ?save для более подробной информации.

После сохранения файла RData вы можете закомментировать этапы медленной загрузки и суммирования данных, а также этап сохранения и просто загрузить данные следующим образом:

load("~/myProject/cachedData/VLDF.RData")

Этот ответ не являетсязависит от редактора.Он работает одинаково для Emacs, TextMate и т. Д. Вы можете сохранить в любом месте на вашем компьютере.Тем не менее, я рекомендую хранить медленный код в вашем файле R-скрипта, чтобы вы всегда могли знать, откуда пришел ваш RData-файл, и при необходимости восстановить его из исходных данных.

3 голосов
/ 28 июля 2010

Не вдаваясь в подробности, я обычно придерживаюсь одного из трех подходов:

  1. Используйте assign, чтобы присвоить уникальное имя каждому важному объекту на протяжении всего выполнения. Затем добавьте if(exists(...)) get(...) в верхней части каждой функции, чтобы получить значение, или же пересчитайте его. (так же, как предложение Дирка)
  2. Используйте cacheSweave с моими Sweave документами. Это сделает всю работу за вас кэшированием вычислений и автоматически получит их. Это действительно тривиально: просто используйте драйвер cacheSweave и добавьте этот флаг в каждый блок: <<..., cache=true>>=
  3. Используйте save и load для сохранения окружающей среды в критические моменты, снова убедившись, что все имена уникальны.
3 голосов
/ 27 июля 2010

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

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