У меня проблемы с передачей аргументов через рекурсивный вызов функции integrate
.Вот простой пример, который иллюстрирует мою головоломку.
Рассмотрим функцию foo1
, которая требует параметр x
и возвращает некоторое преобразование x
.Например:
foo1 = function(x, alpha = 1.5) {
return(x^alpha)
}
Теперь рассмотрим функцию foo2
, которая также требует x
и возвращает другое преобразование:
foo2 = function(x, y, z) {
return(x * y * z)
}
Теперь рассмотрим функцию bar
, которая возвращаетконечный интеграл (от x
до xMax
) любой foo
-подобной функции, но принимает вектор с несколькими значениями для x
:
bar = function(xVals, xMax, ..., fun) {
return(
sapply(
xVals,
function(xVal) integrate(f = fun, lower = xVal, upper = xMax, ...)$value)
)
}
Обратите внимание, что параметр foo1
alpha
будет передано как часть ...
:
bar(10:20, 100, alpha = 1.5, fun = foo1)
и foo2
, параметры y
и z
также будут переданы как часть ...
:
bar(10:20, 100, y = 2, z = 4, fun = foo2)
Мне нравится это расположение, потому что другие обязательные параметры для integrate
также могут быть переданы как часть ...
.Например, чтобы изменить значение по умолчанию параметра subdivisions
функции integrate
, вызываемой bar
, можно просто указать:
bar(10:20, 100, y = 2, z = 4, fun = foo2, subdivisions = 200L)
Теперь рассмотрим функцию, которая интегрирует bar
из xStart в xEnd, но принимает векторы для нескольких значений для xStart и xEnd.Это может выглядеть так:
integrateBar = function(xStart, xEnd, xMax, ..., fun) {
aMatrix = cbind(xStart, xEnd)
result =
apply(
aMatrix,
1,
function(xRange) integrate(bar, xRange[1], xRange[2], xMax, ..., fun = fun)$value
)
return(result)
}
Так что это нормально и довольно просто, пока я не захочу вызвать integrateBar
, но изменить значение аргумента subdivisions
для функции integrate
, вызываемой в bar
.Если я использую:
integrateBar(10:20, 40, 100, alpha = 1.5, subdivisions = 200L, fun = foo1)
аргумент subdivisions
захватывается и используется функцией integrate
в integrateBar
и не передается в bar
.Такое поведение желательно - иногда.Но иногда я также хочу иметь возможность оставить subdivisions
установленным по умолчанию для вызова integrate
в integrateBar
, но изменить его для вызова integrate
в bar
.Может кто-нибудь сказать мне элегантный способ сделать последнее?
Я хочу изменить формальности для bar
, но я стараюсь не делать это слишком неуклюжим, потому что я тоже хочу вызвать bar
напрямую.Было бы очень хорошо, если бы был какой-то трюк R, чтобы аргумент subdivisions
был бы проигнорирован первой обнаруженной функцией интегрирования, но доступной для второй.
Лучшее решение, которое у меня есть, - написать оболочкудля integrate
, который использует параметр SUBDIVISIONS
и вызывает обертку из bar
.Если я не получу лучшего ответа, я опубликую это решение.