Когда стоит использовать `remove` в функциях R? - PullRequest
3 голосов
/ 08 июля 2019

Какие факторы мне следует учитывать при принятии решения о remove переменной, которая больше не будет использоваться в функции?

Вот странный пример:

DivideByLower <- function (a, b) {
  if (a > b) {
    tmp <- a
    a <- b
    b <- tmp
    remove(tmp) # When should I include this line?
  }

  # Return:
  a / b
}

IЯ понимаю, что tmp будет удалено после завершения функции, но стоит ли мне беспокоиться об ее удалении раньше?

1 Ответ

4 голосов
/ 08 июля 2019

С Усовершенствованный Хэдли Уикхем R :

В некоторых языках вы должны явно удалять неиспользуемые объекты для их память должна быть возвращена. R использует альтернативный подход: мусор коллекция (или GC для краткости). GC автоматически освобождает память, когда Объект больше не используется. Это происходит путем отслеживания количества имен. указывать на каждый объект, и когда нет имен, указывающих на объект, он удаляет этот объект.

В случае, если вы описываете сборку мусора, вы освободите память.

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

Больше информации, все еще в книге Хэдли, можно найти в главе о фабриках функций .

function_factory <- function(x){
  force(x)
  y <- "bar"
  fun <- function(z){
    sprintf("x, y, and z are all accessible and their values are '%s', '%s', and '%s'",
            x, y, z)
  }
  fun
}

manufactured_function <- function_factory("foo")
manufactured_function("baz")
#> [1] "x, y, and z are all accessible and their values are 'foo', 'bar', and 'baz'"

Создано в 2019-07-08 пакетом Представить (v0.3.0)

В этом случае, если вы хотите контролировать, какие переменные доступны в окружающей среде, или убедитесь, что не загромождаете свою память, вы можете удалить ненужные объекты, используя rm / remove как вы, или как я предпочитаю, завернутый в on.exit заявление.

Другой случай, в котором я мог бы использовать rm, - это если я хочу получить доступ к переменным из родительской среды без риска переопределения их внутри функции, но в этом случае часто возможно и чище использовать eval.parent.

y <- 2
z <- 3
test0 <- function(x, var){
  y <- 1
  x + eval(substitute(var))
}

# opps, the value of y is the one defined in the body
test0(0, y)
#> [1] 1
test0(0, z)
#> [1] 3

# but it will work using eval.parent :
test1 <- function(x, var){
  y <- 1
  x + eval.parent(substitute(var))
}
test1(0, y)
#> [1] 2
test1(0, z)
#> [1] 3

# in some cases (better avoided), it can be easier/quick and dirty to do something like :
test2 <- function(x, var){
  y <- 1
  # whatever code using y
  rm(y)
  x + eval(substitute(var))
}
test2(0, y)
#> [1] 2
test2(0, z)
#> [1] 3

Создано в 2019-07-08 пакетом представ. (v0.3.0)

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