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.