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

-----Original Message-----
From: r-help-boun...@r-project.org
[mailto:r-help-boun...@r-project.org] On Behalf Of Peter Dalgaard
Sent: Tuesday, February 16, 2010 1:33 AM
To: Gabor Grothendieck
Cc: r-help@r-project.org
Subject: Re: [R] argh .. if/else .. why?

Gabor Grothendieck wrote:
On Mon, Feb 15, 2010 at 11:24 AM, David Winsemius
<dwinsem...@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

______________________________________________
R-help@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.

Reply via email to