[R] alternative to ifelse

Marc Schwartz marc_schwartz at me.com
Wed Jun 19 20:47:07 CEST 2013


On Jun 19, 2013, at 1:23 PM, Marc Schwartz <marc_schwartz at me.com> wrote:

> 
> On Jun 19, 2013, at 8:24 AM, Brian Perron <beperron at umich.edu> wrote:
> 
>> Greetings:
>> 
>> I am looking for a way to avoid using the ifelse function for
>> constructing a new variable.  More specifically, assume I have a set
>> of variables with scores ranging from 1 to 30.
>> 
>> set.seed(12345)
>> x <- c(1:30)
>> x1 <- sample(x, 15, replace = TRUE)
>> x2 <- sample(x, 15, replace = TRUE)
>> x3 <- sample(x, 15, replace = TRUE)
>> x4 <- sample(x, 15, replace = TRUE)
>> 
>> I want to construct a dichotomous variable that tests whether any of
>> the variables contains the value 1.
>> 
>> newVar <-ifelse(x1 == 1 | x2 == 1 | x3 == 1 | x4 == 1, 1, 0)
>> 
>> I want to avoid the ifelse function because I have a number of large
>> variable lists that will require new variables to be created.  I'm
>> sure there is a simple way to do this, but I haven't had any luck with
>> my search!
>> 
>> Thanks in advance.
>> 
>> Brian
> 
> 
> 
> If each of the vectors will be of the same length, create a matrix that contains each one as a column:
> 
> set.seed(12345)
> x <- c(1:30)
> x1 <- sample(x, 15, replace = TRUE)
> x2 <- sample(x, 15, replace = TRUE)
> x3 <- sample(x, 15, replace = TRUE)
> x4 <- sample(x, 15, replace = TRUE)
> 
>> cbind(x1, x2, x3, x4)
>    x1 x2 x3 x4
> [1,] 22 14 24 10
> [2,] 27 12  1  2
> [3,] 23 13  6  2
> [4,] 27  6 21  2
> [5,] 14 29 12 19
> [6,]  5 14 11 29
> [7,] 10 10 27 25
> [8,] 16 29 28 10
> [9,] 22 22 19  7
> [10,] 30 20  5 22
> [11,]  2 12 24 15
> [12,]  5 21 13 22
> [13,] 23 17 28  3
> [14,]  1  7 24 14
> [15,] 12 15  8  8
> 
> 
> Then you can use:
> 
>> rowSums(cbind(x1, x2, x3, x4) == 1)
> [1] 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0
> 
> 
> which gets you the same result as:
> 
>> ifelse(x1 == 1 | x2 == 1 | x3 == 1 | x4 == 1, 1, 0)
> [1] 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0


Actually, correction. That works in the case where only one of the values in the row is a 1, which happened to fit the example data. If there is a chance that more than one value in a row may be a 1, it returns a value equal to the number of 1's found.

Thus, a more generic approach, I believe, would be:

> sign(rowSums(cbind(x1, x2, x3, x4) == 1))
[1] 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0


Regards,

Marc



More information about the R-help mailing list