I would like to make a new vector with values taken from two existing vectors conditional upon a third. At present I am doing this with a for loop but wonder if there is not a neater way, given some of the very neat things R can do. a<-rep(c("A","B"),50) b<-rep(1,100) c<-rep(2,100) a is thus "A" "B" "A" "B" "A" "B"... b is thus 1 1 1 1 1 1 ... c is thus 2 2 2 2 2 2 ... I want d[i] to be b[i] if a[i]=="A" and c[i] if a[i]=="B". I'm current using a for loop: d<-rep(0,100) # initialise d for(i in 1:length(a)) {if(a[i]=="A") d[i]<-b[i] else d[i]<-c[i]} d is thus 1 2 1 2 1 2 1 2 1 ... Is it possible to do something simpler, say along the lines of the c-style ?: conditional statement, or at least avoiding the for loop. d <- a=="A"?b:c # doesn't work, but you get the idea Thanks in advance, Neil
?ifelse> a<-rep(c("A","B"),50) > b<-rep(1,100) > c<-rep(2,100) > d <- ifelse(a == "A", b, c) > head(d)[1] 1 2 1 2 1 2 On Dec 10, 2007 3:41 PM, Neil Stewart <neil.stewart at warwick.ac.uk> wrote:> I would like to make a new vector with values taken from two existing > vectors conditional upon a third. At present I am doing this with a for loop > but wonder if there is not a neater way, given some of the very neat things > R can do. > > a<-rep(c("A","B"),50) > b<-rep(1,100) > c<-rep(2,100) > > a is thus "A" "B" "A" "B" "A" "B"... > b is thus 1 1 1 1 1 1 ... > c is thus 2 2 2 2 2 2 ... > > I want d[i] to be b[i] if a[i]=="A" and c[i] if a[i]=="B". I'm current using > a for loop: > > d<-rep(0,100) # initialise d > for(i in 1:length(a)) {if(a[i]=="A") d[i]<-b[i] else d[i]<-c[i]} > > d is thus 1 2 1 2 1 2 1 2 1 ... > > Is it possible to do something simpler, say along the lines of the c-style > ?: conditional statement, or at least avoiding the for loop. > > d <- a=="A"?b:c # doesn't work, but you get the idea > > Thanks in advance, > Neil > > ______________________________________________ > 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. >-- Jim Holtman Cincinnati, OH +1 513 646 9390 What is the problem you are trying to solve?
>From: Neil Stewart <neil.stewart at warwick.ac.uk> >Date: 2007/12/10 Mon PM 05:41:34 CST >To: r-help at stat.math.ethz.ch >Subject: [R] Neat conditional assignmentd <- ifelse(a == "A",b,c)>I would like to make a new vector with values taken from two existing >vectors conditional upon a third. At present I am doing this with a for loop >but wonder if there is not a neater way, given some of the very neat things >R can do. > >a<-rep(c("A","B"),50) >b<-rep(1,100) >c<-rep(2,100) > >a is thus "A" "B" "A" "B" "A" "B"... >b is thus 1 1 1 1 1 1 ... >c is thus 2 2 2 2 2 2 ... > >I want d[i] to be b[i] if a[i]=="A" and c[i] if a[i]=="B". I'm current using >a for loop: > >d<-rep(0,100) # initialise d >for(i in 1:length(a)) {if(a[i]=="A") d[i]<-b[i] else d[i]<-c[i]} > >d is thus 1 2 1 2 1 2 1 2 1 ... > >Is it possible to do something simpler, say along the lines of the c-style >?: conditional statement, or at least avoiding the for loop. > >d <- a=="A"?b:c # doesn't work, but you get the idea > >Thanks in advance, >Neil > >______________________________________________ >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.
With this specific example this will work: as.numeric(factor(a)) If that is not the real case but its something else you could try any of these which probably generalize better: (a == "A") + 2 * (a == "B") 1 + (a == "B") ifelse(a == "A", 1, 2) On Dec 10, 2007 6:41 PM, Neil Stewart <neil.stewart at warwick.ac.uk> wrote:> I would like to make a new vector with values taken from two existing > vectors conditional upon a third. At present I am doing this with a for loop > but wonder if there is not a neater way, given some of the very neat things > R can do. > > a<-rep(c("A","B"),50) > b<-rep(1,100) > c<-rep(2,100) > > a is thus "A" "B" "A" "B" "A" "B"... > b is thus 1 1 1 1 1 1 ... > c is thus 2 2 2 2 2 2 ... > > I want d[i] to be b[i] if a[i]=="A" and c[i] if a[i]=="B". I'm current using > a for loop: > > d<-rep(0,100) # initialise d > for(i in 1:length(a)) {if(a[i]=="A") d[i]<-b[i] else d[i]<-c[i]} > > d is thus 1 2 1 2 1 2 1 2 1 ... > > Is it possible to do something simpler, say along the lines of the c-style > ?: conditional statement, or at least avoiding the for loop. > > d <- a=="A"?b:c # doesn't work, but you get the idea > > Thanks in advance, > Neil > > ______________________________________________ > 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. >
On Mon, 10 Dec 2007, Neil Stewart wrote:> I would like to make a new vector with values taken from two existing > vectors conditional upon a third. At present I am doing this with a for loop > but wonder if there is not a neater way, given some of the very neat things > R can do. > > a<-rep(c("A","B"),50) > b<-rep(1,100) > c<-rep(2,100) > > a is thus "A" "B" "A" "B" "A" "B"... > b is thus 1 1 1 1 1 1 ... > c is thus 2 2 2 2 2 2 ... > > I want d[i] to be b[i] if a[i]=="A" and c[i] if a[i]=="B". I'm current using > a for loop: > > d<-rep(0,100) # initialise d > for(i in 1:length(a)) {if(a[i]=="A") d[i]<-b[i] else d[i]<-c[i]} > > d is thus 1 2 1 2 1 2 1 2 1 ... > > Is it possible to do something simpler, say along the lines of the c-style > ?: conditional statement, or at least avoiding the for loop. > > d <- a=="A"?b:c # doesn't work, but you get the idead <- ifelse(a == "A", b, c) is what you want! Z> Thanks in advance, > Neil > > ______________________________________________ > 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. > >
On 10-Dec-07 23:41:34, Neil Stewart wrote:> I would like to make a new vector with values taken from two > existing vectors conditional upon a third. At present I am > doing this with a for loop but wonder if there is not a neater > way, given some of the very neat things R can do. > > a<-rep(c("A","B"),50) > b<-rep(1,100) > c<-rep(2,100) > > a is thus "A" "B" "A" "B" "A" "B"... > b is thus 1 1 1 1 1 1 ... > c is thus 2 2 2 2 2 2 ... > > I want d[i] to be b[i] if a[i]=="A" and c[i] if a[i]=="B". > I'm current using a for loop: > > d<-rep(0,100) # initialise d > for(i in 1:length(a)) {if(a[i]=="A") d[i]<-b[i] else d[i]<-c[i]} > > d is thus 1 2 1 2 1 2 1 2 1 ... > > Is it possible to do something simpler, say along the lines > of the c-style ?: conditional statement, or at least avoiding > the for loop. > > d <- a=="A"?b:c # doesn't work, but you get the idea > > Thanks in advance, > NeilYou could use one of at least two simple approaches. When b and c are numeric, then you could use d <- b*(a=="A") + c*(a=="B") since the numeric operation coerces the logical 'a=="A"' into 1 or 0 according as it is TRUE or FALSE, and vice versa. If b and c are not numeric (and indeed generally, but the above is neater for numeric variables), then: d <- b ; d[a=="B"] <- c[a=="B"] which simply over-writes the b-values in d where a=="B". Hoping this helps, Ted. -------------------------------------------------------------------- E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk> Fax-to-email: +44 (0)870 094 0861 Date: 10-Dec-07 Time: 23:55:45 ------------------------------ XFMail ------------------------------