В 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")
и вот результат:
Функция может быть неявным аргументом другой функции. Так, если в вызове функции 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