Sebastian
Sebastian

Reputation: 2570

Smart way to chain ifelse statements?

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

Answers (3)

talat
talat

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 ifelses 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

akrun
akrun

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

RHertel
RHertel

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

Related Questions