Why can't R's ifelse statements return vectors?


Question

I've found R's ifelse statements to be pretty handy from time to time. For example:

ifelse(TRUE,1,2)
# [1] 1
ifelse(FALSE,1,2)
# [1] 2

But I'm somewhat confused by the following behavior.

ifelse(TRUE,c(1,2),c(3,4))
# [1] 1
ifelse(FALSE,c(1,2),c(3,4))
# [1] 3

Is this a design choice that's above my paygrade?

1
102
5/10/2018 8:43:13 PM

Accepted Answer

The documentation for ifelse states:

ifelse returns a value with the same shape as test which is filled with elements selected from either yes or no depending on whether the element of test is TRUE or FALSE.

Since you are passing test values of length 1, you are getting results of length 1. If you pass longer test vectors, you will get longer results:

> ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4))
[1] 1 4

So ifelse is intended for the specific purpose of testing a vector of booleans and returning a vector of the same length, filled with elements taken from the (vector) yes and no arguments.

It is a common confusion, because of the function's name, to use this when really you want just a normal if () {} else {} construction instead.

83
4/27/2018 4:35:28 PM

I bet you want a simple if statement instead of ifelse - in R, if isn't just a control-flow structure, it can return a value:

> if(TRUE) c(1,2) else c(3,4)
[1] 1 2
> if(FALSE) c(1,2) else c(3,4)
[1] 3 4

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon