Передача аргументов в функцию, которая вызывается другой функцией по имени в R - PullRequest
0 голосов
/ 22 февраля 2019

Я использую две функции, скажем Fun1 и Fun2, обе определены в пакете, поэтому я не могу их изменить.Fun1 вызывает Fun2 следующим образом:

Fun1(x=a_number,y=a_string,fn=Fun2,...)

, где ... - аргументы, используемые Fun2.

Итак, Fun1 называет Fun2 своим именем.Как я могу передать параметры в Fun2 без явного вызова имен параметров?

Предположим, что args - это список параметров, которые я хочу передать Fun2.Если я хочу позвонить только Fun2, это легко сделать следующим образом:

do.call(Fun2,args)

Но этот способ не работает, если Fun2 вызывается Fun1 по его имени.Единственный способ - записать параметры явно следующим образом:

Fun1(x=a_number,y=a_string,fn=Fun2,param1=sth,param2=some_other_thing)

Но этот способ не работает для меня, так как есть очень много параметров Fun2 (не только 2), а также я незнать, какие параметры пользователь хочет изменить.Может быть, пользователь просто хочет изменить param1 и оставить другие по умолчанию.

Кстати, следующее не работает, поскольку Fun1 не принимает ничего, кроме имени функции, для своего аргумента 'fn':

Fun1(x=a_number,y=a_string,fn=do.call(Fun2,args))

РЕДАКТИРОВАТЬ 1:

fn=Fun2 (...) не работает, потому что аргумент "fn" Fun1 получает только имя функции, ничего больше.

РЕДАКТИРОВАТЬ 2:

На самом деле Fun1 это baggedModel и Fun2 это auto.arima, оба они в пакете прогноза.Вот пример:

vec.ts=ts(1:27,start=c(2016,1),frequency=12) #time series
num_blocks=3
block_size=24
baggedModel(vec.ts,
         bootstrapped_series = bld.mbb.bootstrap(vec.ts,num_blocks,block_size),
         fn=auto.arima,...)

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

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Используя упрощенный пример из @GGrothendieck.Вы также можете использовать purrr для создания партиалов (функции с уже заполненными некоторыми параметрами)

library(purrr)
fun1 <- function(x, fn, ...) fn(x) + fn(...)

x <- 3:4
args <- list(1,2)
fun2 <- sum
fun3 <- partial(fun2, !!!args)

fun1(x, fun3)

Здесь мы создаем fun3 с точно так же, как fun, но с 1 и 2 уже переданы в качестве параметров (мы просто склеиваем, требуется purrr> 0,3).

С примером baggedModel вы можете просто передать анонимную функцию и не беспокоиться о многоточии

vec.ts=ts(1:27,start=c(2016,1),frequency=12) #time series
num_blocks=3
block_size=24
baggedModel(vec.ts,
    bootstrapped_series = bld.mbb.bootstrap(vec.ts, num_blocks, block_size),
    fn=function(...) auto.arima(..., d=NA, D=NA)) # or whatever params you want

baggedModel может принимать любой тип функции, это не обязательно должна быть функция с буквальным именем.

0 голосов
/ 22 февраля 2019

Предполагая, что входы fun1, x, fun2 и args, показанные ниже последней строки, запускают fun1.

fun1 <- function(x, fn, ...) fn(x) + fn(...)
x <- 3:4
fun2 <- sum
args <- list(1, 2)


do.call("fun1", c(list(x, fun2), args))
## [1] 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...