>>>>> Uwe Ligges <lig...@statistik.tu-dortmund.de> >>>>> on Sun, 7 Aug 2016 09:51:58 +0200 writes:
> On 06.08.2016 17:30, Duncan Murdoch wrote: >> On 06/08/2016 10:18 AM, Martin Maechler wrote: [.................] >>> Of course, an ifelse2() should also be more efficient than >>> ifelse() in typical "atomic" cases. >> >> I don't think it is obvious how to make it more efficient. ifelse() >> already skips evaluation of yes or no if not needed. (An argument could >> be made that it would be better to guarantee evaluation of both, but >> it's usually easy enough to do this explicitly, so I don't see a need.) > Same from here: I do not see how this can easily be made more efficient, > since evaluating ony parts causes a lot of copies of objects whichs > slows stuff down, hence you need some complexity in yes and no to make > evaluations of parts of them more efficient on R level. Yes, Duncan and Uwe are right, and my comment "wish" above was mostly misleading. Some of the many small changes to ifelse() since its initial [1998, R version 0.63.3] simple ifelseR0633 <- function (test, yes, no) { ans <- test test <- as.logical(test) nas <- is.na(test) ans[ test] <- rep(yes, length = length(ans))[ test] ans[!test] <- rep(no, length = length(ans))[!test] ans[nas] <- NA ans } were exactly for adding speed in some of these cases. > Anyway, to solve the problem, we may want an add argument to ifelse2() > that allows for specification of the type of the result (as vapply does)? A good idea, probably only needed / desirable if we'd consider a C based version {as vapply} but for the moment I did not want to go there. The current ifelse() is nice with "pre-S3" objects, such as as atomic (named) vectors and (dimnamed) arrays, including matrices, by keeping most attributes for those... and does that relatively efficiently. What I really meant, not above, but earlier when talking about ifelse()'s inefficiency should really *not* have been related to this thread, I'm sorry for that confusion. I mean the fact that many many usages of ifelse() are of the form ifelse(logiFn(x), f1(x), f2(x)) {with f1() or f2() often even being constant} and e.g., in the case where logiFn(x) gives few TRUEs and f1(.) is expensive and f2(.) very cheap (say "constant" NA), it is much more efficient to use ans <- x Y <- logiFn(x) ans[ Y] <- f1(x[ Y]) ans[!Y] <- f2(x[!Y]) as the expensive function is only called on a small subset of the full x. I'm working at the main topic and *am* thanking Duncan for his conceptual analysis and the (few) proposals. Martin > Best, > Uwe >> Duncan Murdoch >> >>> >>> >>> Thank you for your ideas and suggestions. >>> Again, there's no promise of implementation coming along with this >>> e-mail. >>> >>> Martin Maechler >>> ETH Zurich ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel