Smart way to streamline ifelse statements?

When I have to bind ifelse statements, it looks like this:

ifelse(input=="x","x1", ifelse(input=="y","x2", ifelse(input=="z","x3",NA))) 

Is there a smarter way to do this? I am thinking of creating tables and then merging or something like that to make the code look better?

+6
source share
3 answers

Besides the suggestions in the comments, you can also use match as follows.

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 , you could do:

 vec_out <- vals_out[match(vec_in, vals_in)] 

Result

 vec_out # [1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1" 

A small comparison of the 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 
+11
source

You can try a function like this:

 choice <- function(input) { switch(input, "x"="x1", "y"="x2", "z"="x3", NA) } #> choice("x") #[1] "x1" #> choice("z") #[1] "x3" #> choice("other") #[1] NA 
+8
source

Another option would be to use setNames

 unname(setNames(vals_out, vals_in)[vec_in]) #[1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1" 

NOTE. Took an example from the post by @docendo discimus.

+5
source

All Articles