(Background info: ifelse evaluates both of the expressions, even though only one will be returned. EDIT: This is an incorrect statement. See Tommy’s reply)
Is there any example where it makes sense to use ifelse in a non-vectorized situation? I think that “readability” could be a valid answer when we don’t care about small efficiency gains, but besides that, is it ever faster/equivalent/better-in-some-other-way to use ifelse when an if and then else would do the job?
Similarly, if I have a vectorized situation, is ifelse always the best tool to use? It seems strange that both expressions are evaluated. Is it ever faster to loop through one by one and do a normal if and then else? I’m guessing it would make sense only if evaluating the expressions took a really long time. Is there any other alternative that would not involve an explicit loop?
Thanks
First,
ifelsedoes NOT always evaluate both expressions – only if there are bothTRUEandFALSEelements in the test vector.And in my opinion:
ifelseshould not be used in a non-vectorized situation. It is always slower and more error prone to useifelseoverif/else:In vectorized situations though,
ifelsecan be a good choice – but beware that the length and attributes of the result might not be what you expect (as above, and I considerifelsebroken in that respect).Here’s an example:
tstis of length 5 and has a class. I’d expect the result to be of length 10 and have no class, but that isn’t what happens – it gets an incompatible class and length 5!Why would I expect the length to be 10? Because most functions in R “cycle” the shorter vector to match the longer:
…But
ifelseonly cycles the yes/no arguments to match the length of the tst argument.Why would I expect the class (and other attributes) to not be copied from the test object? Because
<which returns a logical vector does not copy class and attributes from its (typically numeric) arguments. It doesn’t do that because it would typically be very wrong.Finally, can it be more efficient to “do it yourself”? Well, it seems that
ifelseis not a primitive likeif, and it needs some special code to handleNA. If you don’t haveNAs, it can be faster to do it yourself.