[R] argh .. if/else .. why?

David Winsemius dwinsemius at comcast.net
Tue Feb 16 18:59:43 CET 2010


On Feb 16, 2010, at 12:15 PM, William Dunlap wrote:

>> -----Original Message-----
>> From: r-help-bounces at r-project.org
>> [mailto:r-help-bounces at r-project.org] On Behalf Of Peter Dalgaard
>> Sent: Tuesday, February 16, 2010 1:33 AM
>> To: Gabor Grothendieck
>> Cc: r-help at r-project.org
>> Subject: Re: [R] argh .. if/else .. why?
>>
>> Gabor Grothendieck wrote:
>>> On Mon, Feb 15, 2010 at 11:24 AM, David Winsemius
>>> <dwinsemius at comcast.net> wrote:
>>>> On Feb 15, 2010, at 11:01 AM, hadley wickham wrote:
>>>>
>>>>>> I, personally, utilize the
>> ifelse(test,statement,statement) function when
>>>>>> possible over the methodology outlined.
>>>>> if + else and ifelse perform quite different tasks, and
>> in general can
>>>>> not (and should not) be exchanged.  In particular, note that for
>>>>> ifelse, "the class attribute of the result is taken from
>> 'test' and
>>>>> may be inappropriate for the values selected from 'yes'
>> and  'no'".
>>>> I have always been puzzled by that bit of advice/knowledge
>> on the help page.
>>>> "test" will of necessity be of class "logical", and yet I
>> regularly succeed
>>>> in producing numeric and character vectors with ifelse. In
>> fact ifelse would
>>>> be rather limited in utility if it only returned logical vectors.
>>>>
>>>
>>> I think it had intended to refer to oldClass rather than class.
>>>
>>>> oldClass(TRUE)
>>> NULL
>>>> oldClass(ifelse(TRUE, 1, 2))
>>> NULL
>>
>> Well, it does date back to S v.3, but the docs do say class
>> _attribute_
>> and "logical" & friends aren't. It happens with all attributes, and I
>> suspect that the original intention was for things like this to work
>>
>>> ifelse(matrix(c(T,T,F,F),2),1,2)
>>     [,1] [,2]
>> [1,]    1    2
>> [2,]    1    2
>>
>> I can't think of a situation where it is actually useful to copy the
>> class attribute from the condition to the result.
>
> The container-related attributes of ifelse's first argument
> can be profitably copied to the output.  E.g., for classes
> "matrix" and "ts", which can contain a variety of primitive
> data types, we get:
>> m<-matrix(1:12,3,4)
>> ifelse(m>5, TRUE, FALSE) # return a matrix the shape of m
>        [,1]  [,2] [,3] [,4]
>  [1,] FALSE FALSE TRUE TRUE
>  [2,] FALSE FALSE TRUE TRUE
>  [3,] FALSE  TRUE TRUE TRUE
>> t <- ts(1:5, start=2010, freq=12)
>> ifelse(t>3, TRUE, FALSE) # return a ts like t
>         Jan   Feb   Mar   Apr   May
>  2010 FALSE FALSE FALSE  TRUE  TRUE
>

Thanks, Bill that is very helpful. It's possible that the same notion  
was expressed earlier but I didn't "get it" until your version.  The  
message I take away is that as long as the functional evaluation (of  
for example ">") produces a "vectorish" arrangement of logicals having  
some additional structure, that structure is being  preserved by the  
indexing within ifelse. Looking at the code of ifelse is helpful in  
this regard, and it also answers my question about the evaluation/ 
performance issues. Whenever the antecedents are a mixture of T and F,  
then _all_ of the positive and negative consequents will be evaluated  
before they are then selectively transferred to the result.

-- 
David
> Bill Dunlap
> Spotfire, TIBCO Software
> wdunlap tibco.com
>
>> Presumably, the idea
>> is that of the three possibilities, only the condition attributes are
>> unambiguous (think if(cond, A, B) vs. if(!cond, B, A)), so if
>> any set of
>> attributes should be copied, those are the ones.
>>
>> -- 
>>   O__  ---- Peter Dalgaard             Øster Farimagsgade 5, Entr.B
>>  c/ /'_ --- Dept. of Biostatistics     PO Box 2099, 1014 Cph. K

>

David Winsemius, MD
Heritage Laboratories
West Hartford, CT



More information about the R-help mailing list