2

Say I have multiple if conditions, under which different values are assigned to a variable. For instance:

x <- rep(c(1, 2, 3, 4, 5, 6, 7, 8), 4)
for(i in length(x)) {
    if(x[i] == 2) {
      x[i] <- 10
    }
    if(x[i] == 4) {
      x[i] <- 12
    }
    ## and there are more similar if conditions 
    ## ......
}

In general, I'd like to replace the numbers in this vector with other numbers according to specific conditions. Is there a simpler way to do this without writing such a long loop?

tonytonov
  • 25,060
  • 16
  • 82
  • 98
FINNNNN
  • 167
  • 1
  • 2
  • 12
  • For 2-3 consecutive `if` statements it is possible to use nested `ifelse`. But in your case you are probably missing something more straightforward like `x[x==2] <- 10` and so on, without any `for` or `if`. – tonytonov May 21 '14 at 13:59
  • @tonytonov Unless the desired behavior is to only check and affect the last element of the vector; that's what the example code does. – Matthew Lundberg May 21 '14 at 14:00
  • One option here would be to use a [switch statement](http://stackoverflow.com/questions/7825501/switch-statement-usage) – ydaetskcoR May 21 '14 at 14:11
  • @MatthewLundberg That one is difficult to spot, nice catch. Though I presume this is merely a typo. OP, did you mean `for (i in 1:length(x))`? – tonytonov May 21 '14 at 14:25
  • @tonytonov oh yes...this is a typo.. Thank you, I found your solution most suitable for my condition. – FINNNNN May 22 '14 at 02:04

2 Answers2

4

If your x is small non-zero integers, make a lookup table as a simple vector:

lut=c(10,12,13,55,99,12,12,12,99,1010)
lut[x]
 [1] 10 12 13 55 99 12 12 12 10 12 13 55 99 12 12 12 10 12 13 55 99 12 12 12 10
 [26] 12 13 55 99 12 12 12

For other keys, use a list and characterify all the things:

> lut = list("999"=1, "8"=2, "foo"=223)
> unlist(lut[c("999","999","8","8","8","foo")])
 999 999   8   8   8 foo 
   1   1   2   2   2 223 
Spacedman
  • 92,590
  • 12
  • 140
  • 224
3

You don't necessarily need any if statements. You could create a vector of values you want to change x to, then change them all directly with replace

> x <- rep(c(1, 2, 3, 4, 5, 6, 7, 8), 4)    
> inds <- sapply(c(2, 4), function(z) which(x == z))
> vals <- c(rep(10, nrow(inds)), rep(12, nrow(inds)))
> replace(x, inds, vals)
##  [1]  1 10  3 12  5  6  7  8  1 10  3 12  5  6  7  8  1 10  3 12  5  6
## [23]  7  8  1 10  3 12  5  6  7  8
Rich Scriven
  • 97,041
  • 11
  • 181
  • 245