Каков наилучший способ избежать передачи кадра данных? - PullRequest
12 голосов
/ 28 февраля 2009

У меня есть 12 data.frame с для работы. Они похожи, и я должен выполнить одну и ту же обработку для каждого, поэтому я написал функцию, которая принимает data.frame, обрабатывает ее, а затем возвращает data.frame. Это работает. Но я боюсь, что обхожу вокруг очень большую структуру. Возможно, я делаю временные копии (не так ли?) Это не может быть эффективным. Каков наилучший способ избежать прохождения data.frame вокруг?

doSomething <- function(df) {
  // do something with the data frame, df
  return(df)
}

Ответы [ 3 ]

10 голосов
/ 05 марта 2009

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

Лучший способ убедиться в этом - создать пример. Если вы находитесь в Windows, откройте диспетчер задач Windows. Если вы работаете в Linux, откройте окно терминала и выполните команду top. Я собираюсь предположить Windows в этом примере. В R запустите следующее:

col1<-rnorm(1000000,0,1)
col2<-rnorm(1000000,1,2)
myframe<-data.frame(col1,col2)

rm(col1)
rm(col2)
gc()

это создает пару векторов, называемых col1 и col2, затем объединяет их в кадр данных, называемый myframe. Затем он сбрасывает векторы и запускает сборку мусора. Посмотрите в диспетчере задач Windows на использование mem для задачи Rgui.exe. Когда я запускаю R, он использует около 19 мегабайт памяти. После того, как я выполню вышеупомянутые команды, моя машина использует чуть менее 35 мегабайт для R.

Теперь попробуйте это:

myframe<-myframe+1

использование вашей памяти для R должно превысить 144 мегабайта. Если вы форсируете сборку мусора с помощью gc (), вы увидите, что он уменьшится примерно до 35 мегабайт. Чтобы попробовать это с помощью функции, вы можете сделать следующее:

doSomething <- function(df) {
    df<-df+1-1
return(df)
}
myframe<-doSomething(myframe)

при запуске кода выше, использование памяти увеличится до 160 мег или около того. Запуск gc () вернет его обратно до 35 мег.

Так что же делать со всем этим? Что ж, выполнение операции вне функции не намного эффективнее (с точки зрения памяти), чем выполнение ее в функции. Сборка мусора очень хорошо очищает вещи. Вы должны заставить gc () работать? Вероятно, не так, как он будет запускаться автоматически по мере необходимости, я просто запустил его выше, чтобы показать, как это влияет на использование памяти.

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

9 голосов
/ 05 марта 2009

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

0 голосов
/ 01 мая 2013

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

Вы можете передавать окружения в R, которые содержат от 1 до всех ваших переменных. Но, вероятно, вам не нужно об этом беспокоиться.

[Вы также можете сделать что-то подобное с классами. Я только в настоящее время понимаю, как использовать классы для полиморфных функций - и заметьте, что существует более 1 системы классов.]

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