Skip to content

ifelse when test is shorter than yes/no

1 message · Vadim Ogranovich

#
It does work as documented. My question was why it was designed to work
this way. I can not think of a practical situation when someone might
want to ifelse() on a 'test' that is shorter than yes/no w/o expecting
'test' to recycle (therefore I was asking for a warning).

I find this behavior inconsistent with the (spirit of) R's recycling
rules. For example if 'test', 'yes', 'no' are all of the same length
then the following two expressions are equivalent:

1.
x <- ifelse(test, yes, no)

2.
x <- no; x[test] <- yes[test]

This equivalence breaks when 'test' is shorter than yes/no: in the
second case 'test' will be recycled. And I don't see a good reason for
having them behave differently.

If I had to implement ifelse() I'd probably do:

ifelse2 <- function(test, yes, no) {
	x <- rep(no, length.out=max(length(test), length(yes),
length(no)))
	x[test] <- yes[test]

	x
}

(If there is interest I can extend it to take care of NA-s and submit as
a (trivial) patch)


Here is a simple test:
[1]  1 -2  3 -4  5 -1  7 -3  9 -5



Maybe it will help if I tell how I stumbled upon this problem. I had two
m*n matrices, 'yes' and 'no', and a 'test' vector of length m. I wanted
to create a m*n matrix which has 'yes' rows where test==TRUE and 'no'
rows otherwise. So I did

x <- matrix(ifelse(test, yes, no), nrow(yes), ncol(yes))

priding myself for doing it the "whole object way" ... and 'test' did
not recycle (in full accordance with the help page) w/o a warning.


Thanks,
Vadim