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 () ? Lets take a careful look. First, for the sake of concreteness, lets 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 hasnt done so before, because it hasnt 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 latters 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 <wdun...@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-boun...@r-project.org [mailto:r-help-boun...@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.dun...@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]]
______________________________________________ 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.