Каков наилучший способ избежать передачи кадра данных?

StackOverflow https://stackoverflow.com/questions/596819

  •  09-09-2019
  •  | 
  •  

Вопрос

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

doSomething <- function(df) {
  // do something with the data frame, df
  return(df)
}
Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top