Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using a list of possible values in a switch command

Is it possible to provide a kind of list of possible values for my switch function. I would love to keep everything automatically updated, if someone provides a wrong parameter.

I use the {} for each condition, because I will execute more then just this variable declaration in my function, I will do several things within this 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=', '))))

I would love to have something like a list where I can just paste the names to get the possible values. So the ideal solution would like a little bit like this, but without an error message :-)

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=', '))))
like image 960
drmariod Avatar asked Jul 21 '15 11:07

drmariod


2 Answers

The switch function is redundant, you can simply subset a list of values directly:

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

switch is an odd beast in R. I’ve never really found it useful.

If you require more complex actions to be performed, consider using a list of functions:

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

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

I don’t think this can be smartly achieved with switch but it can of course be wrapped into its own little function. Note that unlike Hadley’s answer, all the above avoids partial argument name matching, which is a huge source of error and belongs banished from the face of the Earth.

like image 54
Konrad Rudolph Avatar answered Oct 15 '22 17:10

Konrad Rudolph


Instead of switch, you could use match.arg() and subsetting:

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

filename <- filenames[[con]]

Note that this allows partial matching of con, which may or may not be helpful for your use case.

like image 23
hadley Avatar answered Oct 15 '22 17:10

hadley