2015-06-11 5 views
4

У меня возникла ситуация, когда я написал функцию R, ComplexResult, которая вычисляет дорогостоящий результат, который позже будут использовать две другие отдельные функции: LaterFuncA и LaterFuncB.Хорошая практика сохранения результата функции для последующего использования в R

Я хочу сохранить результат ComplexResult где-нибудь, так что и LaterFuncA, и LaterFuncB могут его использовать, и его не нужно пересчитывать. Результат ComplexResult - это большая матрица, которую нужно вычислить только один раз, а затем повторно использовать позже.

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

# run ComplexResult and get the result 
cmplx.res <- ComplexResult(arg1, arg2) 

# store the result in the global environment. 
# NB this would not be run from a function 
assign("CachedComplexResult", cmplx.res, envir = .GlobalEnv) 

Это все, что нужно делать? Единственным другим подходом, который я могу представить, является наличие большой функции «обертки», например:

MyWrapperFunction <- function(arg1, arg2) { 
    cmplx.res <- ComplexResult(arg1, arg2) 

    res.a <- LaterFuncA(cmplx.res) 
    res.b <- LaterFuncB(cmplx.res) 

    # do more stuff here ... 
} 

Мысли? Я вообще направляюсь в правильном направлении с любым из вышеперечисленных? Или есть вариант C, который более хитрый? :)

+0

с 'cmplx.res <- ComplexResult (arg1, arg2)' вы выполняете присвоение, поэтому вам не нужно делать это 2 раза. В моей практике лучший способ хранения больших таблиц/матриц находится в файле «.txt». 'write.table' и' read.table' работают очень быстро –

+3

'save (object, file =" filename ")', если вы хотите снова использовать объект 'load (file =" filename ")' – The6thSense

ответ

3

Общий ответ: вы должны сериализовать/десериализовать свой большой объект для дальнейшего использования. R способ сделать это с помощью saveRDS/readRDS:

## save a single object to file 
saveRDS(cmplx.res, "cmplx.res.rds") 
## restore it under a different name 
cmplx2.res <- readRDS("cmplx.res.rds") 
+0

и использовать memoise в добавление физического кеша. –

1

Это назначить GlobalEnv:

CachedComplexResult <- ComplexResult(arg1, arg2) 

Для хранения Я хотел бы использовать:

write.table(CachedComplexResult, file = "complex_res.txt") 

И затем использовать его непосредственно:

LaterFuncA(read.table("complex_res.txt")) 
+1

Локальный оператор присваивания ['<-'] (https://stat.ethz.ch/R-manual/R-devel/library/base/html/assignOps.html) присваивает окружение. Если это произойдет в глобальной области, то оно действительно будет присвоено ['.GlobalEnv'] (https://stat.ethz.ch/R-manual/R-devel/library/base/html/environment.html) , однако, если это происходит внутри функции, то она будет назначаться среде оценки вызова функции. – bgoldst

+0

Оператор переадресации '<< -' всегда будет присваивать глобальной среде при условии, что в промежуточной родительской среде нет переменной закрытия этого имени. Тем не менее, эксперты R часто рекомендуют использовать его в качестве плохой практики, хотя я иногда использовал его для использования. – bgoldst

+0

Да, вы правы, я полагаю, что в этом случае он выполнял ту же операцию 2 раза: с оператором '<-' и с функцией' assign'. И если вы хотите назначить глобальное внутри функции, я согласен с тем, что лучше использовать функцию 'assign', а не' '' '' operator –

0

Ваш адрес h работает для сохранения в локальной памяти; другие ответы объяснили сохранение глобальной памяти или файла. Вот некоторые соображения на , почему вы бы сделали то или другое.

Сохранить в файл: это самый медленный, так что делайте это только в том случае, если ваш процесс неустойчив, и вы ожидаете, что он сильно сработает, и вам нужно подобрать кусочки, где он остановился, или если вам просто нужно сохранить состояние время от времени, когда скорость/производительность не вызывает беспокойства.

Сохранить на глобальном уровне: если вам нужен доступ из нескольких точек в большой программе R.

Смежные вопросы