I'd like to use a switch statement to branch according to the first two characters of a string. In the example shown below, I'd like to return "Apple" with either "aabb" or "aacc"
test<-c("aabb", "aacc", "bbbb")
foo <- Vectorize(function(a) {
switch(as.character(a),
"^aa" = "Apple",
"bbbb" = "Grape",
"Unknown")
}, "a")
> foo(test)
aabb aacc bbbb
"Unknown" "Unknown" "Grape"
I can get the statement to work if there is an exact match, but I can't figure out how to get a match using only the first two characters. Maybe there is a way using Regex? As shown, I've tried to use ^
to match the beginning of the string (which works with grep
) but it doesn't work.
I think I could use nested ifelse
statements with grepl
but can it work using switch
?
According to manual, this is impossible with switch
because it only allows exact match:
switch(EXPR, ...)
If EXPR evaluates to a character string then that string is matched (exactly) to the names of the elements in
...
.
But you can do it with case_when
in dplyr
:
foo <- function(x){
dplyr::case_when(
grepl('^aa', x) ~ 'Apple',
x == 'bbbb' ~ 'Grape',
TRUE ~ 'Unknown'
)
}
foo(test)
# [1] "Apple" "Apple" "Grape"
Use substr()
to extract the first two letters; use setNames()
to propagate the full names rather than abbreviation to the answer
> X = setNames(substr(test, 1, 2), test)
> sapply(X, switch, aa="Apple", bb = "Grape", "Unknown")
aabb aacc bbbb
"Apple" "Apple" "Grape"
this might work:
regex_switch<-function(.v,...)
{
e<-enexprs(...)
i<-min(which(str_detect(.v,names(e))))
eval(e[[i]],parent.frame())
}
> map_chr(
c("aaaa","bb","aabbaa"),
regex_switch,
"^aa"="Apple","^bbbb"="Grape","^*$"="Unknown"
)
[1] "Apple" "Unknown" "Apple"
>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.