Duncan,

Your solution seems so much simpler. I was reading The Art of R Programming
and it says the following:


g=c("M","F","F","I","M","M","F",

ifelse (g == "M", 1, ifelse (g == "F", 2, 3))

[1] 1 2 2 3 1 1 2

What actually happens in that nested ifelse () ? Let’s take a careful look.
First, for the sake of concreteness, let’s find what the formal argument
names are in the function ifelse ():

args(ifelse)

function (test, yes, no)

NULL

Remember, for each element of test that is true, the function evaluates to
the corresponding element in yes. Similarly, if test [11 is false, the
function evaluates to no [1] . All values so generated are returned together
in a vector.
**************
MY COMMENT: so the first vector seems to be conditional seems to be
evaluated in full to the full boolean vector.
************
In our case here, R will execute the outer ifelse () call first, in which
test
is g == "M", and yes is 1 (recycled); no will (later) be the result of
executing
ifelse (g=="F", 2, 3). Now since test [11 is true, we generate yes [1]
which is
1. So, the first element of the return value of our outer call will be 1.

Next R will evaluate test[2] . That is false, so R needs to find no[2] . R
now
needs to execute the inner ifelse () call. It hasn’t done so before, because
it hasn’t needed it until now. R uses the principle of lazy evaluation,
meaning that an expression is not computed until it is needed.
***********
MY COMMENT: The above sentence seems to be relevant.
**********

R will now evaluate ifelse (g=="F", 2, 3), yielding (3,2,2,3,3,3,2); this
is no
for the outer ifelse () call, so the latter’s second return element will be
 the second element of (3,2,2,3,3,3,2), which is 2.
***********
MY COMMENT: So this is evaluated at least this once completely.
*************


When the outer ifelse () call gets to test [41 , it will see that value to
be
false and thus will return no [41 . Since R had already computed no, it has
the value needed, which is 3.
***************
MY COMMENT: I am not sure if the implecation here is that the indexing is
managed or not.


On Mon, Dec 2, 2013 at 5:16 PM, William Dunlap <wdunlap@tibco.com> wrote:

> > It seems so inefficient.
>
> But ifelse knows nothing about the expressions given
> as its second and third arguments -- it only sees their
> values after they are evaluated.  Even if it could see the
> expressions, it would not be able to assume that f(x[i])
> is the same as f(x)[i] or things like
>    ifelse(x>0, cumsum(x), cumsum(-x))
> would not work.
>
> You can avoid the computing all of f(x) and then extracting
> a few elements from it by doing something like
>    x <- c("Wednesday", "Monday", "Wednesday")
>    z1 <- character(length(x))
>    z1[x=="Monday"] <- "Mon"
>    z1[x=="Tuesday"] <- "Tue"
>    z1[x=="Wednesday"] <- "Wed"
> or
>    LongDayNames <- c("Monday","Tuesday","Wednesday")
>    ShortDayNames <- c("Mon", "Tue", "Wed")
>    z2 <- character(length(x))
>    for(i in seq_along(LongDayNames)) {
>       z2[x==LongDayNames[i]] <- ShortDayNames[i]
>    }
>
> To avoid the repeated x==value[i] you can use match(x, values).
>    z3 <- ShortDayNames[match(x, LongDayNames)]
>
> z1, z2, and z3 are identical  character vectors.
>
> Or, you can use factors.
>    > factor(x, levels=LongDayNames, labels=ShortDayNames)
>    [1] Wed Mon Wed
>    Levels: Mon Tue Wed
>
> Bill Dunlap
> Spotfire, TIBCO Software
> wdunlap tibco.com
>
>
> > -----Original Message-----
> > From: r-help-bounces@r-project.org [mailto:r-help-bounces@r-project.org]
> On Behalf
> > Of Bill
> > Sent: Monday, December 02, 2013 4:50 PM
> > To: Duncan Murdoch
> > Cc: r-help@r-project.org
> > Subject: Re: [R] ifelse -does it "manage the indexing"?
> >
> > It seems so inefficient. I mean the whole first vector will be evaluated.
> > Then if the second if is run the whole vector will be evaluated again.
> Then
> > if the next if is run the whole vector will be evaluted again. And so on.
> > And this could be only to test the first element (if it is false for each
> > if statement). Then this would be repeated again and again. Is that
> really
> > the way it works? Or am I not thinking clearly?
> >
> >
> > On Mon, Dec 2, 2013 at 4:48 PM, Duncan Murdoch
> > <murdoch.duncan@gmail.com>wrote:
> >
> > > On 13-12-02 7:33 PM, Bill wrote:
> > >
> > >> ifelse ((day_of_week == "Monday"),1,
> > >>    ifelse ((day_of_week == "Tuesday"),2,
> > >>    ifelse ((day_of_week == "Wednesday"),3,
> > >>    ifelse ((day_of_week == "Thursday"),4,
> > >>    ifelse ((day_of_week == "Friday"),5,
> > >>    ifelse ((day_of_week == "Saturday"),6,7)))))))
> > >>
> > >>
> > >>    In code like the above, day_of_week is a vector and so day_of_week
> ==
> > >> "Monday" will result in a boolean vector. Suppose day_of_week is
> Monday,
> > >> Thursday, Friday, Tuesday. So day_of_week == "Monday" will be
> > >> True,False,False,False. I think that ifelse will test the first
> element
> > >> and
> > >> it will generate a 1. At this point it will not have run day_of_week
> ==
> > >> "Tuesday" yet. Then it will test the second element of day_of_week
> and it
> > >> will be false and this will cause it to evaluate day_of_week ==
> "Tuesday".
> > >> My question would be, does the evaluation of day_of_week == "Tuesday"
> > >> result in the generation of an entire boolean vector (which would be
> in
> > >> this case False,False,False,True) or does the ifelse "manage the
> indexing"
> > >> so that it only tests the second element of the original vector
> (which is
> > >> Thursday) and for that matter does it therefore not even bother to
> > >> generate
> > >> the first boolean vector I mentioned above (True,False,False,False)
> but
> > >> rather just checks the first element?
> > >>    Not sure if I have explained this well but if you understand I
> would
> > >> appreciate a reply.
> > >>
> > >
> > > See the help for the function.  If any element of the test is true, the
> > > full first vector will be evaluated.  If any element is false, the
> second
> > > one will be evaluated.  There are no shortcuts of the kind you
> describe.
> > >
> > > Duncan Murdoch
> > >
> > >
> >
> >       [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > 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.
>

	[[alternative HTML version deleted]]

