I\'ve got a little issue with the switch statement in R. The following code is OK ... :
value = \"B\"
switch(value,
\"A\"={
print(\"
Im sure there are easier ways but you can use alist
and do.call
xlist = c("A","B", "C")
value = "B"
myList <- alist(print(xlist[1]), print(xlist[2]), print(xlist[3]), print("Other !!!"))
myList <- setNames(myList, c(xlist, ''))
do.call(switch, c(EXPR = value, myList))
Examples:
> value = "D"
> do.call(switch, c(EXPR = value, myList))
[1] "Other !!!"
> value = "A"
> do.call(switch, c(EXPR = value, myList))
[1] "A"
> value = "C"
> do.call(switch, c(EXPR = value, myList))
[1] "C"
> value = "B"
> do.call(switch, c(EXPR = value, myList))
[1] "B"
Your mistake is that the switch
alternatives require literal names and can't have a variable name. You're naming the arguments of the function and they internally become names of items in a list. In fact, the "" aren't necessary around your A
, B
, C
in your first example. Knowing that, the problem becomes more obvious. Try assigning b <- "B"
and then using b
as the second switch item. That will fail as well because it's not going to resolve the variable name, just take it as a literal. In your case it fails with a syntax problem because alist[1]
isn't a valid alternative label without quotes.
Similar restrictions are placed on switch statements in other languages as well. Think of the alternatives in the switch as being labelled like names of items in a list
structure. They can be pretty much anything quoted but they don't need quotes and then there are restrictions on what they can be. What they cannot be is variable.
As you recognize in your question, there are alternative ways to do this. Here's a concise one that will be much faster than a switch
statement (even if you did manage to solve the variable list items problem indirectly with a call function).
i <- which(alist == value)
if (length(i) == 1){
print( paste0( 'value = ', alist[i]) )
}else {
print( 'Other !!' ) }
Try using vapply
.
i.e. in your case
vapply(mychr,switch,"",...SWITCH ARGS...)
I think what you would want is:
vapply(mychr,switch,"",
mychr[1]=mychr[1],mychr[2]=mychr[2],mychr[3]=mychr[3],"Other !!!")
The ==
operator works on vectors, so what you need is just:
> a <- c("A", "B", "C")
> a
[1] "A" "B" "C"
> b <- "B"
> b == a
[1] FALSE TRUE FALSE
Alternatively, you can use which
> which(a == b)
[1] 2
Note that can return several elements if a
contains more than one instance of b
You can then proceed using an if
or ifelse
or switch
statement on the result.
PS: you should avoid using list
as a variable name, as it is a standard function in R