[Rd] ifelse() woes ... can we agree on a ifelse2() ?

Bob Rudis bob at rud.is
Sat Aug 6 16:43:39 CEST 2016


have you tried seeing if `dplyr::if_else` behaves more to your liking?

On Sat, Aug 6, 2016 at 10:20 AM Martin Maechler <maechler at stat.math.ethz.ch>
wrote:

> Dear R-devel readers,
> ( = people interested in the improvement and development of R).
>
> This is not the first time that this topic is raised.
> and I am in now state to promise that anything will result from
> this thread ...
>
> Still, I think the majority among us has agreed that
>
> 1) you should never use ifelse(test, yes, no)
>    if you know that length(test) == 1, in which case
>           if(test) yes else no
>    is much preferable  (though not equivalent: ifelse(NA, 1, 0) !)
>
> 2) it is potentially inefficient by design since it (almost
>    always) evaluates both 'yes' and 'no' independent of 'test'.
>
> 3) is a nice syntax in principle, and so is often used, also by
>    myself, inspite of '2)'  just because nicely self-explaining
>    code is sometimes clearly preferable to more efficient but
>    less readable code.
>
> 4) it is too late to change ifelse() fundamentally, because it
>    works according to its documentation
>    (and I think very much the same as in S and S-PLUS) and has
>    done so for ages.
>
> ---- and if you don't agree with  1) -- 4)  you may pretend for
>      a moment instead of starting to discuss them thoroughly.
>
> Recently, a useR has alerted me to the fact that my Rmpfr's
> package arbitrary (high) precision numbers don't work for a
> relatively simple function.
>
> As I found the reason was that that simple function used
>  ifelse(.,.,.)
> and the problem was that the (*simplified*) gist of ifelse(test, yes, no)
> is
>
>   test <- as.logical(test)
>   ans <- test
>   ans[ test] <- yes
>   ans[!test] <- no
>
> and in case of Rmpfr, the problem is that
>
>    <logical>[<logical>]  <-  <mpfr>
>
> cannot work correctly
>
>     [[ maybe it could in a future R, if I could define a method
>
>        setReplaceMethod("[", c("logical,"logical","mpfr"),
>                         function(x,i,value) .........)
>
>        but that currently fails as the C-low-level dispatch for '[<-'
>        does not look at the full signature
>      ]]
>
> I vaguely remember having seen proposals for
> light weight substitutes for ifelse(),  called
>  ifelse1() or
>  ifelse2() etc...
>
> and I wonder if we should not try to see if there was a version
> that could go into "base R" (maybe the 'utils' package, not
>                              'base'; that's not so important).
>
> One difference to ifelse() would be that the type/mode/class of the result
> is not initialized by logical, by default but rather by the
> "common type" of  yes and no ... maybe determined  by  c()'ing
> parts of those.
> The idea was that this would work for most S3 and S4 objects for
> which logical 'length', (logical) indexing '[', and 'rep()' works.
>
> One possibility would also be to consider  a "numbers-only" or
> rather "same type"-only {e.g., would also work for characters}
> version.
>
> Of course, an ifelse2()  should also be more efficient than
> ifelse() in typical "atomic" cases.
>
>
> 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 at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

	[[alternative HTML version deleted]]



More information about the R-devel mailing list