Alex Rivera | Logout

using Reduce/do.call with ifelse

Asked 2012-08-03T15:00:31.890
10

This is purely a curiosity (learning more about Reduce). There are way better methods to achieve what I'm doing and I am not interested in them.

Some people use a series of nested ifelse commands to recode/look up something. Maybe it looks like this:

set.seed(10); x <- sample(letters[1:10], 300, T)
ifelse(x=="a", 1, 
    ifelse(x=="b", 2,
    ifelse(x=="c", 3, 
    ifelse(x=="d", 4, 5))))

Is there a way to use either do.call or Reduce with the ifelse to get the job done a little more eloquently?

Edit
Report

2 Answers

3

Try this:

> library(gsubfn)
> strapply(x, ".", list(a = 1, b = 2, c = 3, d = 4, 5), simplify = TRUE)
  [1] 5 4 5 5 1 3 3 3 5 5 5 5 2 5 4 5 1 3 4 5 5 5 5 4 5 5 5 3 5 4 5 1 2 5 5 5 5
 [38] 5 5 5 3 3 1 5 3 2 1 5 2 5 4 5 3 5 2 5 5 5 4 5 1 2 5 4 5 5 5 5 1 3 1 5 5 5
 [75] 1 5 4 5 3 3 5 5 3 5 3 1 5 3 2 2 5 5 5 5 4 5 3 5 5 1 4 1 4 5 5 5 5 5 5 5 5
[112] 5 2 5 5 5 3 5 5 5 2 4 4 5 3 3 5 4 5 5 5 1 5 3 4 3 5 5 2 5 5 3 1 5 2 5 5 5
[149] 1 5 5 2 1 2 4 2 2 3 5 2 5 5 5 5 5 3 5 5 5 5 5 5 5 5 5 5 2 3 5 4 4 2 5 5 5
[186] 5 5 5 5 2 1 1 1 5 5 5 5 3 5 5 3 5 5 5 2 5 5 5 3 5 5 5 5 5 1 5 5 5 5 2 2 5
[223] 5 5 4 3 4 5 5 4 5 5 5 3 5 3 5 5 5 5 4 5 5 1 5 5 2 5 5 5 2 5 5 3 2 5 4 5 2
[260] 5 5 3 5 5 1 4 3 5 4 5 2 5 5 3 5 5 5 5 5 1 1 5 2 5 1 5 5 5 5 5 5 5 5 5 5 5
[297] 5 1 5 2
answered 2012-08-03T16:52:02.283
0

Here is an attempt. It is neither beautiful nor does it use ifelse:

f <- function(w,s) {
  if(is.null(s$old)) 
    w$output[is.na(w$output)] <- s$new
  else 
    w$output[w$input==s$old] <- s$new
  return(w)
}

set.seed(10); x <- sample(letters[1:10], 300, T)

subst <- list(
  list(old="a", new=1), 
  list(old="b", new=2),
  list(old="c", new=3),
  list(old="d", new=4),
  list(old=NULL, new=5)
)
workplace <- list(
  input=x,
  output=rep(NA, length(x))
)

Reduce(f, subst, workplace)
answered 2012-08-03T21:59:02.107

Your Answer