[R] ifelse() fill order and recycling rules [Sec=Unclassified]

Rolf Turner r.turner at auckland.ac.nz
Thu Aug 28 05:01:22 CEST 2008


On 28/08/2008, at 11:30 AM, John McKinlay wrote:

> Hi all,
>
> Using R v2.7.1, platform i386-pc-mingw32
>
> Can someone please shed some light on the behaviour of ifelse() for  
> me?
> My intent is to calc relative proportions of z$b, at the same time
> subsetting z$b based on z$a. I could attack the problem other ways
> (suggestions welcome) but I am also intrigued by the _order_ in which
> ifelse seems to assign values, and how recycling works. For instance,
> 	
> z <- data.frame(a = c(1,2,3,4,1), b = 6:10)
> z$c <- ifelse(z$a > 1, z$b[z$a > 1]/sum(z$b[z$a > 1]), NA)
> z # seems to have filled z$c by row 4,2,3
>   a  b         c
> 1 1  6        NA
> 2 2  7 0.3333333
> 3 3  8 0.3750000
> 4 4  9 0.2916667
> 5 1 10        NA
>
> z$b[z$a > 1]/sum(z$b[z$a > 1]) # order looks fine here
> [1] 0.2916667 0.3333333 0.3750000
>
>
> z$d <- ifelse(z$a > 1, 6:8, NA) # fills by row 4,2,3 (as above) z$e <-
> ifelse(z$a > 1, 6:7, NA) # recycling, but why values 7,6,7 instead of
> 6,7,6 ?
>
> z
>   a  b         c  d  e
> 1 1  6        NA NA NA
> 2 2  7 0.3333333  7  7
> 3 3  8 0.3750000  8  6
> 4 4  9 0.2916667  6  7
> 5 1 10        NA NA NA
>
> TIA for any insight into how ifelse is filling/recycling in this
> instance. I know there's not much code in ifelse, but it's still not
> immediately apparent to me why I'm getting what I'm seeing.

(a) Don't cloud the issue by dragging in data frames.  As was  
recently pointed
out in a discussion on how to learn R, not all data structures need  
be rectangular.

(b) The function ifelse() takes 3 vector arguments: test, yes, and no.
The help (RTFM) for ifelse() says quite explicitly that if 'yes' and  
'no' are too
short, their elements are recycled.

(c) So if test is a > 1, yes is 6:7 and no is NA you get (the following
needs to be read in fixed width font and no mucking around by an  
arrogant
mailer that thinks it knows your mind better than your do):

	test	yes	no
         ----    ---     --
	FALSE	6	NA
	TRUE	7	NA
	TRUE 	6	NA
	TRUE	7	NA
	FALSE	6	NA

Consequently the result of ifelse(a>1,6:7,NA) is c(NA,7,6,7,NA).

What's the problem?

	cheers,

		Rolf Turner

######################################################################
Attention:\ This e-mail message is privileged and confid...{{dropped:9}}



More information about the R-help mailing list