Используя список возможных значений в команде переключателя

Можно ли предоставить список возможных значений для моей функции switch. Я бы хотел, чтобы все автоматически обновлялось, если кто-то предоставляет неправильный параметр.

Я использую {} для каждого условия, потому что я буду выполнять больше, чем просто объявление этой переменной в моей функции, я сделаю несколько вещей внутри этого переключателя.

switch(con,
       val1={
         filename <- 'SILAC-DML_with_PDF.R'
       },
       val2={
         filename <- 'SILAC-DML_with_PDF.R'
       },
       stop(sprintf('"%s" is an unknown condition type, please use one of "%s".\n',
                    con, paste(c('val1','val2'), collapse=', '))))

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

my_list <- list(val1=filename <- 'a.R',
                val2=filename <- 'b.R')
switch(con,
       my_list,
       stop(sprintf('"%s" is an unknown condition type, please use one of "%s".\n',
                    con, names(my_list), collapse=', '))))

Ответ 1

Функция switch является избыточной, вы можете просто подмножить список значений напрямую:

alternatives = list(val1 = 'SILAC-DML_with_PDF.R',
                    val2 = 'SILAC-DML_with_PDF.R')
result = alternatives[[con]]
if (is.null(result))
    stop(…)

... switch - нечетное зверь в R. Я никогда не считал его полезным.

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

alternatives = list(
    val1 = function () { message('foo') },
    val2 = function () { message('bar') }
)

if (! con %in% names(alternatives))
    stop(…)
result = alternatives[[con]]()

Я не думаю, что это может быть достигнуто с помощью switch, но это, конечно, может быть завернуто в свою небольшую функцию. Обратите внимание, что в отличие от ответа Хэдлиса, все вышеперечисленное позволяет избежать совпадения парциальных аргументов, что является огромным источником ошибок и принадлежит изгнанным с лица Земли.

Ответ 2

Вместо переключателя вы можете использовать match.arg() и подмножество:

filenames <- c(
  val1 = "a.R",
  val2 = "b.R"
)
con <- match.arg(con, names(filenames))

filename <- filenames[[con]]

Обратите внимание, что это позволяет частичное совпадение con, которое может быть или не быть полезным для вашего использования.