Параметр функции в качестве аргумента в функции R

Я пытаюсь написать общую функцию для вычисления вероятностей покрытия для интервальной оценки биномиальных пропорций в R. Я намерен сделать это для различных методов доверительных интервалов, например, Уолда, Клоппера-Пирсона, HPD-интервалов для разных априорных значений.

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

Например, для точного интервала Клоппера-Пирсона у меня есть следующая функция:

# Coverage for Exact interval
ExactCoverage <- function(n) {
p <- seq(0,1,.001)
x <- 0:n

# value of dist
dist <- sapply(p, dbinom, size=n, x=x)

# interval
int <- Exact(x,n)

# indicator function
ind <- sapply(p, function(x) cbind(int[,1] <= x & int[,2] >= x))

list(coverage = apply(ind*dist, 2, sum), p = p)
}

Где Exact (x,n) - это просто функция для вычисления соответствующего интервала. Я бы хотел

Coverage <- function(n, FUN, ...)
...
# interval
int <- FUN(...)

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

Спасибо Джеймс

2 ответа

Решение

В R функция может быть предоставлена ​​как аргумент функции. Синтаксис соответствует синтаксису нефункциональных объектов.

Вот пример функции.

myfun <- function(x, FUN) {
  FUN(x)
}

Эта функция применяет функцию FUN к объекту x,

Несколько примеров с вектором, включающим числа от 1 до 10:

vec <- 1:10 

> myfun(vec, mean)
[1] 5.5
> myfun(vec, sum)
[1] 55
> myfun(vec, diff)
[1] 1 1 1 1 1 1 1 1 1

Это не ограничивается встроенными функциями, но работает с любой функцией:

> myfun(vec, function(obj) sum(obj) / length(obj))
[1] 5.5

mymean <- function(obj){
  sum(obj) / length(obj)
}
> myfun(vec, mymean)
[1] 5.5

Вы также можете сохранить имя функции как символьную переменную и вызвать ее с помощью do.call().

> test = c(1:5)
> do.call(mean, list(test))
[1] 3
> 
> func = 'mean'
> do.call(func, list(test))
[1] 3

Текст Хэдли дает отличный (и простой) пример:

randomise <- function(f) f(runif(1e3))

randomise(mean)
#> [1] 0.5059199
randomise(mean)
#> [1] 0.5029048
randomise(sum)
#> [1] 504.245
Другие вопросы по тегам