在 switch 命令中使用可能值的列表

using a list of possible values in a switch command

是否可以为我的 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=', '))))

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 巧妙地实现,但它当然可以包装到它自己的小函数中。请注意,与 Hadley 的回答不同,以上所有内容都避免了部分参数名称匹配,这是一个巨大的错误来源,应该从地球表面被驱逐。

您可以使用 match.arg() 和子集来代替开关:

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

filename <- filenames[[con]]

请注意,这允许 con 的部分匹配,这可能对您的用例有帮助,也可能没有帮助。