Список объектов в качестве аргументов функции с переопределяемыми значениями по умолчанию для элемента списка - PullRequest
0 голосов
/ 08 октября 2018

У меня есть функция R, которая принимает большое количество аргументов (18), которые я хотел бы передать в виде списка.Когда я запускаю эту функцию, так сказать, вручную, я обычно хочу использовать все значения по умолчанию, кроме одного или двух, но я также хочу запускать эту же функцию много раз с различными комбинациями элементов по умолчанию и элементов не по умолчанию, которые яхотел бы собрать программно в виде списков.

Я знаю, что мог бы просто иметь свои 18+ аргументов в качестве отдельных формалей и затем собирать их в список внутри функции, но я хотел бы иметь список по умолчанию для формальности, а затем иметьэлементы также имеют значения по умолчанию.Например:

> f <<- function(x, y = list(a=0, b=3)) {with(y, (x + a + b))}
> f(1)
[1] 4
> f(x=1, y$a = 1)
Error: unexpected '=' in "f(x=1, y$a ="

(или альтернативно)

In y$a <- 1 :
 Error in eval(substitute(expr), data, enclos = parent.frame()) : 
  object 'a' not found 

за исключением вывода с 5, а не с ошибкой.Я подозреваю, что нет никакого способа сделать это, потому что R не распознает назначения в списке как создающие значения по умолчанию, но только как создающие именованные элементы.Но может быть с формой присвоения формалей?или с помощью умного использования do.call?

1 Ответ

0 голосов
/ 08 октября 2018

Вот несколько альтернатив:

1) modifyList Используйте modifyList для обработки значений по умолчанию.

f1 <- function(x, y = list()) {
  defaults <- list(a = 0, b = 3)
  with(modifyList(defaults, y), {
    x + a + b
  })
}

f1(x = 1)
## [1] 4
f1(x = 1, y = list(a = 1))
## [1] 5

2) do.call Другая возможность состоит в том, чтобы иметь две функции.Первый не использует список, а второй (который вызывает пользователь) использует do.call для вызова первого.

f2impl <- function(x, a = 0, b = 3) x + a + b
f2 <- function(x, y = list()) do.call("f2impl", c(x, y))

f2(x = 1)
## [1] 4
f2(x = 1, y = list(a = 1))
## [1] 5
...