[R] Neat conditional assignment

(Ted Harding) Ted.Harding at manchester.ac.uk
Tue Dec 11 00:56:01 CET 2007


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,
> Neil

You 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 ------------------------------



More information about the R-help mailing list