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
as.numeric(x1 == 1 | x2 == 1 | x3 == 1 | x4 == 1) On Wed, Jun 19, 2013 at 9:24 AM, Brian Perron <beperron@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 > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
On Wed, 19 Jun 2013, Brian Perron <beperron at umich.edu> writes:> 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 >Hi Brian, put all your x into a matrix and use apply: X <- cbind(x1, x2, x3, x4) apply(X, 1, function(x) if (any(x == 1L)) 1 else 0) ## [1] 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 or, since TRUE and FALSE evaluate to 1 and 0 when coerced to numeric: as.integer(apply(X, 1, function(x) any(x == 1L))) ## [1] 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 Regards, Enrico -- Enrico Schumann Lucerne, Switzerland http://enricoschumann.net
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. > > BrianIf 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 Regards, Marc Schwartz
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. > > BrianIf 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 Regards, Marc Schwartz
Hi, May bet this also helps: 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) indx<-1+2*(x1==1)+4*(x2==1)+8*(x3==1)+16*(x4==1) ?as.numeric(indx!=1) #[1] 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 #Speed comparisons set.seed(1235) x <- c(1:1e7) x1 <- sample(x, 1e7, replace = TRUE) x2 <- sample(x, 1e7, replace = TRUE) x3 <- sample(x, 1e7, replace = TRUE) x4 <- sample(x, 1e7, replace = TRUE) system.time(res1 <-ifelse(x1 == 1 | x2 == 1 | x3 == 1 | x4 == 1, 1, 0)) ?# user? system elapsed ?# 3.740?? 0.256?? 4.003 system.time(res2<-as.numeric(x1 == 1 | x2 == 1 | x3 == 1 | x4 == 1)) # user? system elapsed #? 0.996?? 0.076?? 1.077 system.time({indx<-1+2*(x1==1)+4*(x2==1)+8*(x3==1)+16*(x4==1) ?res3<-as.numeric(indx!=1)}) # user? system elapsed #? 0.596?? 0.240?? 0.840 system.time(res4<-rowSums(cbind(x1, x2, x3, x4) == 1)) # user? system elapsed #? 0.732?? 0.192?? 0.926 ? system.time(res4New<-sign(rowSums(cbind(x1, x2, x3, x4) == 1))) ?# user? system elapsed ?# 0.824?? 0.232?? 1.062 X <- cbind(x1, x2, x3, x4) system.time({ res5<-as.integer(apply(X, 1, function(x) any(x == 1L)))}) ?# user? system elapsed #113.308?? 0.208 113.729 system.time(res6<-apply(X, 1, function(x) if (any(x == 1L)) 1 else 0)) ?#user? system elapsed # 61.660?? 0.216? 61.989 identical(res1,res6) #[1] TRUE identical(res1,res2) #[1] TRUE ?identical(res1,res3) #[1] TRUE identical(res1,res4) #[1] TRUE ?identical(res1,res4New) #[1] TRUE A.K. ----- Original Message ----- From: Brian Perron <beperron at umich.edu> To: r-help at r-project.org Cc: Sent: Wednesday, June 19, 2013 9:24 AM Subject: [R] alternative to ifelse 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 ______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.