[R] ifelse statement

Godfrey van der Linden gvdl at mac.com
Thu Jul 8 03:06:08 CEST 2010


On 2010-07-08, at 10:33 , Duncan Murdoch wrote:

> On 07/07/2010 7:32 PM, Gabor Grothendieck wrote:
>> On Wed, Jul 7, 2010 at 7:22 PM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
>>  
>>> On 07/07/2010 5:58 PM, karena wrote:
>>>    
>>>> Hi, I am a newbie of R, and playing with the "ifelse" statement.
>>>> 
>>>> I have the following codes:
>>>> ## first,
>>>> 
>>>> for(i in 1:3) {
>>>> for(j in 2:4) {
>>>> cor.temp <- cor(iris.allnum[,i], iris.allnum[,j])
>>>> if(i==1 & j==2) corr.iris <- cor.temp
>>>> else corr.iris <- c(corr.iris, cor.temp)
>>>> }
>>>> }
>>>> 
>>>> this code is working fine.
>>>> 
>>>> I also tried to perform the same thing in another way with "ifelse":
>>>> for(i in 1:3) {
>>>> for(j in 2:4) {
>>>> cor.temp <- cor(iris.allnum[,i], iris.allnum[,j])
>>>> corr.iris <- ifelse(i==1 & j==2, cor.temp, c(corr.iris, cor.temp))
>>>> }
>>>> }
>>>> 
>>>> This is not working. Seems the value of "c(corr.iris, cor.temp)" has not
>>>> been assigned to corr.iris, even  when the (i==1 & j==2) is not satisfied.
>>>> 
>>>> what's the problem here?
>>>>      
>>> See ?ifelse.  It computes something the same shape as the test object.  In
>>> your case the test is the result of
>>> 
>>> i==1 & j==2
>>> 
>>> and is a scalar that is either TRUE or FALSE, so the result of ifelse() will
>>> be a scalar too.
>>> 
>>> To do what you want in one line, you can use
>>> 
>>> corr.iris <- if (i==1 && j==2) cor.temp else c(corr.iris, cor.temp)
>>> 
>>> but to most people this looks unnatural, and your original code is what I'd
>>> recommend using.  In this case it makes no difference whether you use & or
>>> && in the test, but in other cases only && makes sense with if, and only &
>>> makes sense with ifelse().
>>>    
>> 
>> Just to quibble I find the
>> 
>>   corr.iris <- if ...
>> 
>> construct easier to understand than
>> 
>>   if (...) corr.iris <- ... else corr.iris <- ...
>> 
>> because in the first case you immediately see that the purpose of the
>> construct is to set corr.iris whereas setting it separately in each
>> leg requires that you must examine more code, i.e. both legs, to make
>> such a determination adding to the mental load.
>>  
> 
> Well, I did say "most people", not "all people".  The reason I think most people prefer the separate statement is that they don't realize that "if (test) value1 else value2" is just a different way to write the function call "`if`(test, value1, value2)", they think of it as a flow-of-control statement, as it is in languages like C.
> 
> Duncan Murdoch

I'm a newbie too, but I'm sort of curious about the functional programming approach

How does the following code fragment work for you

ind <- matrix(c(rep(1:3, each=3), rep(2:4, 3)), nrows=3*3, ncols=2)
result <= ifelse(inds[,1] == 1 & inds[,2] == 2, <dotrue>, <dofalse>)

This code is more concise.

Is it more efficient? I assume a lot of this code is done in C rather than the interpreted for loops around if()else statements.  Is it more memory intensive?

Godfrey



More information about the R-help mailing list