Подтвердить что ты не робот

Написание функций в R, с учетом

Я часто пишу функции, которые должны видеть другие объекты в моей среде. Например:

> a <- 3
> b <- 3
> x <- 1:5
> fn1 <- function(x,a,b) a+b+x
> fn2 <- function(x) a+b+x
> fn1(x,a,b)
[1]  7  8  9 10 11
> fn2(x)
[1]  7  8  9 10 11

Как и ожидалось, обе эти функции идентичны, поскольку fn2 может "видеть" a и b, когда она выполняется. Но всякий раз, когда я начинаю использовать это, через 30 минут я вызываю функцию без одной из необходимых переменных (например, a или b). Если я не воспользуюсь этим, тогда я чувствую, что я пропускаю объекты без необходимости.

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

4b9b3361

Ответ 1

Если я знаю, что мне понадобится функция, параметризованная некоторыми значениями и вызываемая повторно, я избегаю глобальных привязок с помощью закрытия:

make.fn2 <- function(a, b) {
    fn2 <- function(x) {
        return( x + a + b )
    }
    return( fn2 )
}

a <- 2; b <- 3
fn2.1 <- make.fn2(a, b)
fn2.1(3)    # 8
fn2.1(4)    # 9

a <- 4
fn2.2 <- make.fn2(a, b)
fn2.2(3)    # 10
fn2.1(3)    # 8

Это аккуратно избегает ссылок на глобальные переменные, вместо этого используется окружающая среда функции для a и b. Модификация глобальных а и b не приводит к непреднамеренным побочным эффектам при вызове экземпляров fn2.

Ответ 2

Есть причина, по которой некоторые языки не допускают глобальных переменных: они могут легко привести к поломке кода.

Правила определения области видимости в R позволяют вам писать код в ленивом режиме - позволяя функциям использовать переменные в других средах, может сэкономить вам некоторую типизацию, и это отлично подходит для игры в простых случаях.

Если вы делаете что-то дистанционно, однако, я рекомендую вам передать функцию всем переменным, которые ей нужны (или, по крайней мере, провести тщательную проверку работоспособности, чтобы иметь резервную копию в случае, если переменные " t существует).

В приведенном выше примере:

Лучшей практикой является использование fn1.

В качестве альтернативы попробуйте что-то вроде

 fn3 <- function(x)
   {
      if(!exists("a", envir=.GlobalEnv))
      {
         warning("Variable 'a' does not exist in the global environment")
         a <- 1
      }

      if(!exists("b", envir=.GlobalEnv))
      {
         warning("Variable 'b' does not exist in the global environment")
         b <- 2
      }

      x + a + b
   }

Ответ 3

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

Именование глобальных переменных таким образом, что было бы трудно маскировать их локально, может помочь. например: global.pimultiples <- 1:4*pi

Ответ 4

Использование глобальных переменных является общим препятствием на большинстве языков, и R не является исключением. Очень часто короткая функция использует короткие и общие имена переменных, которые могут быть заполнены в глобальной среде. Наиболее безопасно: а) включать все переменные в определение функции; б) не назначать значения по умолчанию. Например, напишите f = function (a, b), а f = function (a = 0, b = NA).