Reputation: 2570
When I have to chain ifelse statements, it looks like:
ifelse(input=="x","x1",
ifelse(input=="y","x2",
ifelse(input=="z","x3",NA)))
Is there a smarter way to do this? I'm thinking about creating tables then merging or something alike just to make the code look better?
Upvotes: 6
Views: 376
Reputation: 70246
Apart from the suggestions in comments you could also use match
in the following way.
Create sample data:
set.seed(1)
vals_in <- c("x", "y", "z") # unique values in your input vector
vec_in <- sample(vals_in, 10, replace = TRUE) # sample from vals_in to create input
vals_out <- c("x1", "x2", "x3") # values to replace
Now, to replace the nested ifelse
s you could do:
vec_out <- vals_out[match(vec_in, vals_in)]
The result is
vec_out
# [1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1"
A little comparison of two approaches:
set.seed(1)
vals_in <- letters
vec_in <- sample(vals_in, 1e7, replace = TRUE)
vals_out <- LETTERS
system.time(vals_out[match(vec_in, vals_in)])
User System verstrichen
0.378 0.020 0.398
system.time(unname(setNames(vals_out, vals_in)[vec_in]))
User System verstrichen
1.020 0.062 1.084
Upvotes: 11
Reputation: 886938
Another option would be using setNames
unname(setNames(vals_out, vals_in)[vec_in])
#[1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1"
NOTE: Taken the example from @docendo discimus post.
Upvotes: 6
Reputation: 23788
You can try a function like this one:
choice <- function(input) {
switch(input,
"x"="x1",
"y"="x2",
"z"="x3",
NA)
}
#> choice("x")
#[1] "x1"
#> choice("z")
#[1] "x3"
#> choice("other")
#[1] NA
Upvotes: 8