2009-02-27 3 views
12

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

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

Последующий вопрос: по завершении «doSomething» команда «rm (doSomething)» освободит объект для сбора мусора, не так ли? – bernie

+0

Адам, да. Ты прав. –

+0

, но имейте в виду, что в приведенном выше примере «doSomething» - это функция, а не данные, поэтому она не очень большая. –

ответ

11

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

Лучший способ увидеть это - создать пример. Если вы находитесь в Windows, откройте диспетчер задач Windows. Если вы находитесь в Linux, откройте окно терминала и запустите верхнюю команду. В этом примере я предполагаю 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()? Вероятно, не так, как он будет запускаться автоматически по мере необходимости, я просто использовал его выше, чтобы показать, как он влияет на использование памяти.

Я надеюсь, что это поможет!

8

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

+3

Вот как работает R, Нил. Хорошая точка зрения. –

1

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

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

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

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