Date Редакция Категория comp Теги R

В R функцию можно передавать в качестве аргумента в другие функции.

Допустим, у вас есть функция toPercent, преобразующая вектор чисел – процентов -- в вектор строк со знаком '%'. В ней используется округление, выполняемое с помощью функции round:

> toPercent <- function(x) {
+   percent <- round(x * 100)
+   paste(percent, "%", sep = "")
+ }

> a <- c(0.15, 1.26, 0.98, 1.02)
> toPercent(a)
[1] "15%"  "126%" "98%"  "102%"

Вдруг, неизвестно по какой причине, вам понадобилось выполнить округление при помощи другой функции – signif. Эта функция позволяет указывать, после какого знака следует округлять число.

Что делать? Писать новую функцию toPercent не слишком разумно, так как она будет почти точной копией предыдущей. Вместо этого слегка изменим toPercent:

toPercent <- function(x, FUN = round, ...) {
  percent <- FUN(x * 100, ...)
  paste(percent, "%", sep = "")
}

Если не указывать явно аргумент FUN, то новая функция будет работать так же, как прежняя – ведь по умолчанию используется всё тот же round. Покажем это:

> a <- c(0.15, 1.26, 0.98, 1.02)
> toPercent(a)
[1] "15%"  "126%" "98%"  "102%"

Вместо многоточия '...' можно указывать дополнительные аргументы, которые будут передаваться функции FUN. Например:

> toPercent(a, FUN = signif, digits = 3)
[1] "15%"  "126%" "98%"  "102%"

Здесь:

  • R присваивает код функции signif аргументу FUN и функция FUN() становится точной копией signif();
  • toPercent принимает аргумент digits (число знаков, после которых signif выполняет округление) и передает его в FUN().

Обратите внимание, что при передаче функции в качестве аргумента используется только имя функции, но не скобки – signif, а не signif(). Последний вариант R трактует как вызов функции, к тому же ошибочный из-за отсутствия аргументов.

Таким образом, открывается широчайший простор для создания функций-"обёрток". Например, нам нужна функция, строящая графики линиями красного цвета. Все остальные её параметры -- такие же, как у стандартной plot().

Создаём обёртку над plot():

plot.red <- function(x, y, ...) {
  plot(x, y, col = "red", ...)
}

применяем её

x <- seq(-pi,pi,.1)
y <- sin(x)
plot.red(x,y, type="l")

и вот результат:

plot_red.png

Функция может быть неявным аргументом другой функции. Так, если в вызове функции g()

g <- function(x, FUN = NULL) {
  if (missing(FUN))
    FUN <- function(x) x^2
  FUN(x)
}

используется только первый аргумент x, без которого никак не обойтись, то "скрытая" функция FUN возводит значение x в квадрат

> g(2)
[1] 4

missing проверяет, не пропущен ли аргумент при вызове функции и, если это так, то запускает FUN.

Функцию FUN можно задать явно. Например, в виде анонимной функции:

> g(2, FUN = function(x) x^3)
[1] 8


Комментарии

comments powered by Disqus